Go实战--Design Patterns in Golang 之工厂模式(简单工厂、工厂方法、抽象工厂)

前端之家收集整理的这篇文章主要介绍了Go实战--Design Patterns in Golang 之工厂模式(简单工厂、工厂方法、抽象工厂)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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

Go语言学习之struct(The way to go)

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)
}

猜你在找的Go相关文章