先看一下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)
}