先看一下golang的Tiobe指数趋势:
可以看到在2017年7月,达到了最高点,之后略有下降。我坚信,2018年的7月,golang还会飙升。
生命不止,继续 go go go !!!
继续,golang中设计模式的探讨。
按照国际惯例,讲完单例模式,接下来就该轮到工厂模式。还是那句话,每个人对设计模式的理解都有所不同,欢迎各位探讨。
何为工厂模式
WIKI:
In class-based programming,the factory method pattern is a creational pattern that uses factory methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created.
百度百科:
工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。
在面向对象的编程语言中(如java,C++)设计模式的概念广为人知,应用的也非常广泛。设计模式让我们的代码变得灵活起来,具有很强的扩展性。但在与C语言比肩的Go语言中,设计模式的概念并没有十分突出,甚至很少听到。在Go的开发中,借鉴design pattern的理念同样回味无穷我们的开发带来极大的便利。
c++中使用工厂模式
纯虚类:
- class IAnimal
- {
- public:
- virtual int GetNumberOfLegs() const = 0;
- virtual void Speak() = 0;
- virtual void Free() = 0;
- };
实现类:
- // IAnimal implementations
- class Cat : public IAnimal
- {
- public:
- int GetNumberOfLegs() const { return 4; }
- void Speak() { cout << "Meow" << endl; }
- void Free() { delete this; }
-
- static IAnimal * __stdcall Create() { return new Cat(); }
- };
-
- class Dog : public IAnimal
- {
- public:
- int GetNumberOfLegs() const { return 4; }
- void Speak() { cout << "Woof" << endl; }
- void Free() { delete this; }
-
- static IAnimal * __stdcall Create() { return new Dog(); }
- };
-
- class Spider : public IAnimal // Yeah it isn’t really an animal…
- {
- public:
- int GetNumberOfLegs() const { return 8; }
- void Speak() { cout << endl; }
- void Free() { delete this; }
-
- static IAnimal * __stdcall Create() { return new Spider(); }
- };
-
- class Horse : public IAnimal
- {
- public:
- int GetNumberOfLegs() const { return 4; }
- void Speak() { cout << "A horse is a horse,of course,of course." << endl; }
- void Free() { delete this; }
-
- static IAnimal * __stdcall Create() { return new Horse(); }
- };
工厂类:
- class AnimalFactory
- {
- private:
- AnimalFactory();
- AnimalFactory(const AnimalFactory &) { }
- AnimalFactory &operator=(const AnimalFactory &) { return *this; }
-
- typedef map FactoryMap;
- FactoryMap m_FactoryMap;
- public:
- ~AnimalFactory() { m_FactoryMap.clear(); }
-
- static AnimalFactory *Get()
- {
- static AnimalFactory instance;
- return &instance;
- }
-
- void Register(const string &animalName,CreateAnimalFn pfnCreate);
- IAnimal *CreateAnimal(const string &animalName);
- };
工厂类实现:
- AnimalFactory::AnimalFactory()
- {
- Register("Horse",&Horse::Create);
- Register("Cat",&Cat::Create);
- Register("Dog",&Dog::Create);
- Register("Spider",&Spider::Create);
- }
-
- void AnimalFactory::Register(const string &animalName,CreateAnimalFn pfnCreate)
- {
- m_FactoryMap[animalName] = pfnCreate;
- }
-
- IAnimal *AnimalFactory::CreateAnimal(const string &animalName)
- {
- FactoryMap::iterator it = m_FactoryMap.find(animalName);
- if( it != m_FactoryMap.end() )
- return it->second();
- return NULL;
- }
使用:
- int main( int argc,char **argv )
- {
- IAnimal *pAnimal = NULL;
- string animalName;
-
- while( pAnimal == NULL )
- {
- cout << "Type the name of an animal or ‘q’ to quit: ";
- cin >> animalName;
-
- if( animalName == "q" )
- break;
-
- IAnimal *pAnimal = AnimalFactory::Get()->CreateAnimal(animalName);
- if( pAnimal )
- {
- cout << "Your animal has " << pAnimal->GetNumberOfLegs() << " legs." << endl;
- cout << "Your animal says: ";
- pAnimal->Speak();
- }
- else
- {
- cout << "That animal doesn’t exist in the farm! Choose another!" << endl;
- }
- if( pAnimal )
- pAnimal->Free();
- pAnimal = NULL;
- animalName.clear();
- }
- return 0;
- }
Struct and Interface
我们知道,golang不是完全的面向对象语言,没有C++或是java中所谓的类。
但是,有struct和interface。这两个知识点是必须要掌握的,弄明白了他们还能理解如何在golang中使用设计模式。
struct:
- type exampleStruct struct{
- num int
- s string
- flag bool
- }
interface:
- type myInterface interface { myFunction() float64 }
Go语言学习之interface(The way to go)
简单工厂、工厂方法、抽象工厂
Stack Overflow:
https://stackoverflow.com/questions/13029261/design-patterns-factory-vs-factory-method-vs-abstract-factory
简单工厂
简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。
Simple Factory Pattern
Definition:
Creates objects without exposing the instantiation logic to the client.
Refers to the newly created object through a common interface
工厂方法
工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。
在同一等级结构中,支持增加任意产品。
Factory Method
Definition:
Defines an interface for creating objects,but let subclasses to decide which class to instantiate
Refers the newly created object through a common interface.
抽象工厂
抽象工厂是应对产品族概念的。比如说,每个汽车公司可能要同时生产轿车,货车,客车,那么每一个工厂都要有创建轿车,货车和客车的方法。
Abstract Factory
Definition:
Abstract Factory offers the interface for creating a family of related objects,without explicitly specifying their classes
golang中简单工厂模式
- package main
-
- import (
- "fmt"
- )
-
- type Operater interface {
- Operate(int,int) int
- }
-
- type AddOperate struct {
- }
-
- func (this *AddOperate) Operate(rhs int,lhs int) int {
- return rhs + lhs
- }
-
- type MultipleOperate struct {
- }
-
- func (this *MultipleOperate) Operate(rhs int,lhs int) int {
- return rhs * lhs
- }
-
- type OperateFactory struct {
- }
-
- func NewOperateFactory() *OperateFactory {
- return &OperateFactory{}
- }
-
- func (this *OperateFactory) CreateOperate(operatename string) Operater {
- switch operatename {
- case "+":
- return &AddOperate{}
- case "*":
- return &MultipleOperate{}
- default:
- panic("无效运算符号")
- return nil
- }
- }
-
- func main() {
- Operator := NewOperateFactory().CreateOperate("+")
- fmt.Printf("add result is %d\n",Operator.Operate(1, 2))
- }
golang中工厂方法模式
- package main
-
- import (
- "fmt"
- )
-
- type Operation struct {
- a float64
- b float64
- }
-
- type OperationI interface {
- GetResult() float64
- SetA(float64)
- SetB(float64)
- }
-
- func (op *Operation) SetA(a float64) {
- op.a = a
- }
-
- func (op *Operation) SetB(b float64) {
- op.b = b
- }
-
- type AddOperation struct {
- Operation
- }
-
- func (this *AddOperation) GetResult() float64 {
- return this.a + this.b
- }
-
- type SubOperation struct {
- Operation
- }
-
- func (this *SubOperation) GetResult() float64 {
- return this.a - this.b
- }
-
- type MulOperation struct {
- Operation
- }
-
- func (this *MulOperation) GetResult() float64 {
- return this.a * this.b
- }
-
- type DivOperation struct {
- Operation
- }
-
- func (this *DivOperation) GetResult() float64 {
- return this.a / this.b
- }
-
- type IFactory interface {
- CreateOperation() Operation
- }
-
- type AddFactory struct {
- }
-
- func (this *AddFactory) CreateOperation() OperationI {
- return &(AddOperation{})
- }
-
- type SubFactory struct {
- }
-
- func (this *SubFactory) CreateOperation() OperationI {
- return &(SubOperation{})
- }
-
- type MulFactory struct {
- }
-
- func (this *MulFactory) CreateOperation() OperationI {
- return &(MulOperation{})
- }
-
- type DivFactory struct {
- }
-
- func (this *DivFactory) CreateOperation() OperationI {
- return &(DivOperation{})
- }
-
- func main() {
- fac := &(AddFactory{})
- oper := fac.CreateOperation()
- oper.SetA(1)
- oper.SetB(2)
- fmt.Println(oper.GetResult())
- }
更具体的例子:
http://matthewbrown.io/2016/01/23/factory-pattern-in-golang/
golang中抽象工厂模式
- package main
-
- import "fmt"
-
- type GirlFriend struct {
- nationality string
- eyesColor string
- language string
- }
-
- type AbstractFactory interface {
- CreateMyLove() GirlFriend
- }
-
- type IndianGirlFriendFactory struct {
- }
-
- type KoreanGirlFriendFactory struct {
- }
-
- func (a IndianGirlFriendFactory) CreateMyLove() GirlFriend {
- return GirlFriend{"Indian","Black","Hindi"}
- }
-
- func (a KoreanGirlFriendFactory) CreateMyLove() GirlFriend {
- return GirlFriend{"Korean","Brown","Korean"}
- }
-
- func getGirlFriend(typeGf string) GirlFriend {
-
- var gffact AbstractFactory
- switch typeGf {
- case "Indian":
- gffact = IndianGirlFriendFactory{}
- return gffact.CreateMyLove()
- case "Korean":
- gffact = KoreanGirlFriendFactory{}
- return gffact.CreateMyLove()
- }
- return GirlFriend{}
- }
-
- func main() {
-
- a := getGirlFriend("Indian")
-
- fmt.Println(a.eyesColor)
- }