go的工厂设计模式

148 阅读4分钟

设计模式是针对软件设计中常见问题的通用、可重用的解决方案。其中,创建型设计模式主要处理对象创建的机制,尝试在不失灵活性和可重用性的情况下创建对象。工厂模式是创建型模式中的一种。

在Go语言中,常见的工厂模式有简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)和抽象工厂模式(Abstract Factory)

  1. 简单工厂模式(Simple Factory)

简单工厂模式其实并不是Go 23种设计模式之一,但它通常被视为是工厂模式的基础。该模式中,工厂类根据传入参数,通过if或switch语句,返回特定对象的实例。

例如,我们有一个用于创建“食物”的工厂。我们有两种食物:Pizza和Burger。

type Food interface {
    Eat()
}

type Pizza struct{}

func (p Pizza) Eat() {
    fmt.Println("This is delicious pizza!")
}

type Burger struct{}

func (b Burger) Eat() {
    fmt.Println("This is amazing burger!")
}

type SimpleFoodFactory struct{}

func (sff SimpleFoodFactory) CreateFood(t string) Food {
    if t == "pizza" {
        return Pizza{}
    } else if t == "burger" {
        return Burger{}
    }
    return nil
}

使用方式:

factory := new(SimpleFoodFactory)
food1 := factory.CreateFood("pizza")
food1.Eat() // This is delicious pizza!

food2 := factory.CreateFood("burger")
food2.Eat() // This is amazing burger!

  1. 工厂方法模式(Factory Method)

在工厂方法模式中,我们提供一个接口用于创建对象,但让实现接口的类决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。

type IAnimal interface {
    Speak() string
}

type Dog struct {}

func (d Dog) Speak() string {
    return "Woof!"
}

type Cat struct {}

func (c Cat) Speak() string {
    return "Meow!"
}

type AnimalFactory interface {
    CreateAnimal() IAnimal
}

type DogFactory struct {}

func (df DogFactory) CreateAnimal() IAnimal {
    return Dog{}
}

type CatFactory struct {}

func (cf CatFactory) CreateAnimal() IAnimal {
    return Cat{}
}

使用方式:

var factory AnimalFactory
factory = new(DogFactory)
animal1 := factory.CreateAnimal()
fmt.Println(animal1.Speak()) // Woof!

factory = new(CatFactory)
animal2 := factory.CreateAnimal()
fmt.Println(animal2.Speak()) // Meow!

  1. 抽象工厂模式(Abstract Factory)

抽象工厂模式用于创建产品族的工厂,所创建的对象是一系列相互关联或相互依赖的产品组合。例如,创建一个形状工厂,可以创建圆形、正方形等,也创建一个颜色工厂,可以创建红色、蓝色等。

type IShape interface {
    Draw() string
}

type Circle struct {}

func (c Circle) Draw() string {
    return "Draw Circle"
}

type Square struct {}

func (s Square) Draw() string {
    return "Draw Square"
}

type IFactory interface {
    CreateShape() IShape
}

type CircleFactory struct {}

func (cf CircleFactory) CreateShape() IShape {
    return Circle{}
}

type SquareFactory struct {}

func (sf SquareFactory) CreateShape() IShape {
    return Square{}
}

使用方式:

var factory IFactory
factory = new(CircleFactory)
shape1 := factory.CreateShape()
fmt.Println(shape1.Draw()) // Draw Circle

factory = new(SquareFactory)
shape2 := factory.CreateShape()
fmt.Println(shape2.Draw()) // Draw Square

工厂模式的本质是"提供一个接口,让那些实现该接口的类来决定实例化哪一个类,并且由调用者决定在何时进行实例化"。其基本思想是创建对象的时候,不将具体类暴露给客户端,而是提供一个创建对象的通用接口,然后我们在接口实现中判断应该创建哪一个类的实例。

这样做的好处是将对象的创建与对象的使用分离,让调用者从具体的产品实现中解耦,只关心产品的接口。当系统中需要替换具体的产品或者增加新的产品时,客户端代码基本上不需要做任何改动,只需要改动工厂类或者配置文件,符合开放封闭原则。

工厂模式根据其具体实现,可以分为简单工厂模式(Simple Factory)、工厂方法模式(Factory Method)和抽象工厂模式(Abstract Factory)。这些工厂模式虽然实现方式不同,但是它们都是为了实现创建者与实际创建对象的解耦。

  • 简单工厂模式:由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类的实例。
  • 工厂方法模式:定义一个创建对象的接口,但由子类决定实例化哪一个类,工厂方法让类的实例化延迟到子类进行。
  • 抽象工厂模式:提供一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体类。

总的来说,工厂模式的本质就是将实际创建对象的工作推迟到子类或者工厂类中,实现一个高层模块不依赖于低层模块,两者可以相互替换,从而提高了系统的可维护性、灵活性和稳定性。能不需要某些设计模式,因为Go的某些特性已经内置了设计模式的思想。