工厂模式是设计模式中的经典模式,工厂模式又可分为以下三种类型:
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
这三种模式可以理解为同一种编程思想的三个版本,从简单到高级不断升级。本文将着重介绍简单工厂模式
。
简单工厂模式
简单工厂模式
(Simple Factory Pattern)指的是专门定义一个类来负责创建其它类的实例,根据参数的不同创建不同类的实例,被创建的实例通常具有共同的父类。简单工厂模式
又被称为静态工厂方法模式
。
我们介绍一种最简单的简单工厂模式
版本,只有一个工厂类SimpleFactory,类中有一个静态创建方法createProduct,该方法根据参数的名称(name)来创建具体的产品(子类)对象,其UML类图如下:
让我们来看一个例子,比如我们有一个工厂(ToyFactory),需要根据玩具的名称,来加工出玩具鸭子(DuckToy)、玩具椅子(ChairToy)、玩具火车(TrainToy),其UML类图如下:
Python实现代码:
# -*- coding: utf-8 -*-
from abc import ABCMeta, abstractmethod
# 玩具抽象类
class Toy(metaclass=ABCMeta):
def __init__(self, name, price):
self.__name = name
self.__price = price
def getName(self):
return self.__name
def getPrice(self):
return self.__price
@abstractmethod
def getMaterial(self):
pass
# 玩具鸭子
class DuckToy(Toy):
def __init__(self, name, price):
super(DuckToy, self).__init__(name, price)
def getMaterial(self):
return 'cotton'
# 玩具椅子
class ChairToy(Toy):
def __init__(self, name, price):
super(ChairToy, self).__init__(name, price)
def getMaterial(self):
return 'wood'
# 玩具火车
class TrainToy(Toy):
def __init__(self, name, price):
super(TrainToy, self).__init__(name, price)
def getMaterial(self):
return 'metal'
# 玩具加工类
class ToyFactory:
def make_toy(self, toy_name):
if toy_name == 'duck':
toy = DuckToy('Duck', 20.0)
elif toy_name == 'chair':
toy = ChairToy('Chair', 50.0)
elif toy_name == 'train':
toy = TrainToy('Train', 100.0)
else:
raise ValueError('unsupported toy name, please choose duck, chair, train.')
return toy
if __name__ == '__main__':
duck_toy = ToyFactory().make_toy('duck')
print('make a %s toy, its material: %s, its price: %s' % (duck_toy.getName(), duck_toy.getMaterial(), duck_toy.getPrice()))
chair_toy = ToyFactory().make_toy('chair')
print('make a %s toy, its material: %s, its price: %s' % (chair_toy.getName(), chair_toy.getMaterial(), chair_toy.getPrice()))
train_toy = ToyFactory().make_toy('train')
print('make a %s toy, its material: %s, its price: %s' % (train_toy.getName(), train_toy.getMaterial(), train_toy.getPrice()))
运行结果:
make a Duck toy, its material: cotton, its price: 20.0
make a Chair toy, its material: wood, its price: 50.0
make a Train toy, its material: metal, its price: 100.0
在该例子中,SimpleFactory为ToyFactory,方法make_toy根据玩具名称来加工不同的玩具类型,当玩具名称为duck时,加工玩具鸭子(DuckToy);当玩具名称为chair时,加工玩具椅子(ChairToy);当玩具名称为train时,加工玩具火车(TrainToy)。
简单工厂模式的优点为:
- 实现简单,结构清晰
- 抽象出一个专门的类来负责某类对象的创建,分割出创建的职责,不能直接创建具体的对象,只需传入适当的参数即可
- 使用者可以不关注具体对象的类名称,只需知道传入什么参数可以创建哪些需要的对象
其缺点为:
- 不易拓展,一旦添加新的产品类型,就不得不修改工厂的创建逻辑,不符合“开放-封闭”原则
- 当产品类型较多时,工厂的创建逻辑可能过于复杂
工厂方法模式
工厂方法模式
是简单工厂模式
的一个升级版本,其含义为定义一个创建对象(实例化对象)的接口,让子类来决定创建哪个类的实例。工厂方法使一个类的实例化延迟到其子类。
为解决上述简单工厂模式
不符合“开放-封闭”原则,我们对SimpleFactory进行拆分,抽象出一个父类Factory,并增加多个子类分别负责创建不同的具体产品,其UML类图如下:
工厂方法模式
的优点为:
- 解决了简单工厂模式不符合“开放-封闭”原则的问题,使程序更容易拓展
- 实现简单
其缺点为:
- 对于有多种分类的产品,或具有二级分类的产品,工厂方法模式不再适用
抽象工厂模式
抽象工厂模式
是工厂方法模式
的升级版本,可以解决具有二级分类的产品的创建问题,其UML类图可以设计如下:
抽象工厂模式
的优点为:
- 解决了具有二级分类的产品的创建
其缺点为:
- 如果产品分类超过二级,则该模式会变得臃肿
- 不能解决产品有多种分类、多种组合的问题
参考文献
- 罗伟富 人人都懂设计模式:从生活中领悟设计模式(Python实现)[B],电子工业出版社