跳到主要内容

工厂方法模式

前言

工厂方法模式是一种创建型设计模式,它定义了一个用于创建对象的接口,但将实际创建工作延迟到子类中。这样每个子类都可以根据需要创建适当的对象类型。工厂方法模式通过引入抽象工厂类,将客户端代码与具体产品类解耦,同时也符合开闭原则,易于扩展和维护。

工厂方法模式的角色组成如下:

  • 工厂:声明返回产品对象的工厂方法的接口。该方法返回的对象类型必须与产品接口类型相匹配。
  • 具体工厂:实现工厂接口的类,会重写基础工厂方法,使其返回不同类型的产品。
  • 产品:生命产品方法的接口。对于所有由具体工厂类及其子类构建的对象,该接口是通用的。
  • 具体产品:实现产品接口的类。

工厂方法适用场景:

  • 程序开发过程中,如果开发者无法预知对象的具体类型机器依赖关系,则可以使用工厂方法模式。工厂方法模式将创建产品的工厂代码与产品代码分离,从而降低代码之间的耦合度。例如,如果需要添加一种新产品,则只需要创建一个新的具体工厂类,然后重写其工厂方法。
  • 如果开发者希望其他开发者可以扩展软件库或框架的内部组件
  • 当一个类希望由它的子类来指定所创建的对象时
  • 当类将创建对象的职责委托给多个帮助子类中的其中一个,并希望能够动态切换。

工厂方法优缺点:

  • 优点
    • 符合开闭原则,易于扩展和维护
    • 将具体产品类的创建逻辑延迟到子类,使得客户端代码与具体产品类解耦
  • 缺点
    • 每增加一个产品,就需要增加一个产品工厂类,导致类的个数增加,系统变得更加复杂
    • 客户端需要知道所使用的具体工厂类
    • 增加了系统的抽象性和理解难度

示例代码

Go

factorymethod/demo.go

package factorymethod

// Operator 是被封装的实际接口
type Operator interface {
SetA(int)
SetB(int)
Result() int
}

// OperatorFactory 是工厂接口
type OperatorFactory interface {
Create() Operator
}

// OperatorBase 是Operator接口实现的基类, 封装公用方法
type OperatorBase struct {
a, b int
}

func (o *OperatorBase) SetA(a int) {
o.a = a
}

func (o *OperatorBase) SetB(b int) {
o.b = b
}

// PlusOperatorFactory 是PlusOperator的工厂类
type PlusOperatorFactory struct {}

func (PlusOperatorFactory) Create() Operator {
return &PlusOperator{
OperatorBase: &OperatorBase{},
}
}

type PlusOperator struct {
*OperatorBase
}

// Result 获取结果
func (o PlusOperator) Result() int {
return o.a + o.b
}

// MinusOperatorFactory 是MinusOperator的工厂类
type MinusOperatorFactory struct {}

func (MinusOperatorFactory) Create() Operator {
return &MinusOperator{
OperatorBase: &OperatorBase{},
}
}

type MinusOperator struct {
*OperatorBase
}

func (o MinusOperator) Result() int {
return o.a - o.b
}

单元测试:factorymethod/demo_test.go

package factorymethod

import (
"testing"
)

func compute(factory OperatorFactory, a, b int) int {
op := factory.Create()
op.SetA(a)
op.SetB(b)
return op.Result()
}

func TestOperatory(t *testing.T) {
var factory OperatorFactory

factory = PlusOperatorFactory{}
if compute(factory, 1, 2) != 3 {
t.Fatal("error with factory method pattern")
}

factory = MinusOperatorFactory{}
if compute(factory, 1, 2) != -1 {
t.Fatal("error with factory method pattern")
}
}

Python

from abc import ABC, abstractmethod

# 定义抽象产品类
class Car(ABC):
@abstractmethod
def drive(self):
pass

# 定义具体产品类
class Byd(Car):
def drive(self):
return "Byd is driving"

class Weilai(Car):
def drive(self):
return "Weilai is driving"

# 定义抽象工厂类
class CarFactory(ABC):
@abstractmethod
def create_car(self):
pass

# 定义具体工厂类
class BydFactory(CarFactory):
def create_car(self):
return Byd()

class WeilaiFactory(CarFactory):
def create_car(self):
return Weilai()

if __name__ == "__main__":
byd_factory = BydFactory()
car = byd_factory.create_car()
print(car.drive())
weilai_factory = WeilaiFactory()
car = weilai_factory.create_car()
print(car.drive())