Python设计模式——工厂方法模式

简单工厂模式

UML图




当Client调用Factory的create_type方法,Factory会根据传递的参数,生产出Product1或Product2

工厂方法模式

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

define an interface to create objects, but instead of the factory being responsible for the object creation, the responsibility is deferred to the subclass that decides the class to be instantiated.

抽象产品类Product负责定义产品的共性,实现对事物最抽象的定义;
Creator为抽象创造类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的。

UML图



实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
class Section(metaclass=ABCMeta):
@abstractmethod
def describe(self):
pass
class PersonalSection(Section):
def describe(self):
print("Personal Section")
class AlbumSection(Section):
def describe(self):
print("Album Section")
class PatentSection(Section):
def describe(self):
print("Patent Section")
class PublicationSection(Section):
def describe(self):
print("Publication Section")
class Profile(metaclass=ABCMeta):
def __init__(self):
self.sections = []
self.createProfile()
@abstractmethod
def createProfile(self):
pass
def getSections(self):
return self.sections
def addSections(self, section):
self.sections.append(section)
class linkedin(Profile):
def createProfile(self):
self.addSections(PersonalSection())
self.addSections(PatentSection())
self.addSections(PublicationSection())
class facebook(Profile):
def createProfile(self):
self.addSections(PersonalSection())
self.addSections(AlbumSection())
if __name__ == '__main__':
profile_type = input("Which Profile you'd like to create? [LinkedIn or FaceBook]\n")
profile = eval(profile_type.lower())()
print("Creating Profile..", type(profile).__name__)
print("Profile has sections --", profile.getSections())

对比简单工厂模式,你就会发现,两者的不同在于工厂方法模式多了一个抽象工厂类(在此例中为Profile)。所以“定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。”

优点

  1. 良好的封装性。一个对象创建时有条件约束的,如一个调用者需要一个具体的产品对象,只要知道这个产品的类名(或者约束字符串)就可以了。屏蔽了产品类。
  2. 扩展性优秀。只要扩展一个工厂类就行。
  3. 解耦

工厂方法模式是new一个对象的代替品,但需要考虑其增加代码复杂度的成本。
例如设计一个连接邮件服务器的框架,把POP3,IMAP,HTTP三种连接方式作为产品类。
定义一个工厂方法,根据不同的传入条件,产生不同的产品类,从而选择不同的连接方式。


抽象工厂模式

UML图




Product1与Product2是由关联的,而其又分别从两个工厂生产出来的,用户通过使用抽象工厂的接口,指挥具体的工厂生产出产品

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class PizzaFactory(metaclass=ABCMeta):
@abstractmethod
def createVegPizza(self):
pass
@abstractmethod
def createNonVegPizza(self):
pass
class IndianPizzaFactory(PizzaFactory):
def createVegPizza(self):
return DeluxVeggiePizza()
def createNonVegPizza(self):
return ChickenPizza()
class USPizzaFactory(PizzaFactory):
def createVegPizza(self):
return MexicanVegPizza()
def createNonVegPizza(self):
return HamPizza()
# 素食披萨
class VegPizza(metaclass=ABCMeta):
@abstractmethod
def prepare(self, VegPizza):
pass
# 非素食披萨
class NonVegPizza(metaclass=ABCMeta):
@abstractmethod
def serve(self, VegPizza):
pass
class DeluxVeggiePizza(VegPizza):
def prepare(self):
print("Prepare ", type(self).__name__)
class ChickenPizza(NonVegPizza):
def serve(self, VegPizza):
print(type(self).__name__, " is served with Chicken on ", type(VegPizza).__name__)
class MexicanVegPizza(VegPizza):
def prepare(self):
print("Prepare ", type(self).__name__)
class HamPizza(NonVegPizza):
def serve(self, VegPizza):
print(type(self).__name__, " is served with Ham on ", type(VegPizza).__name__)
class PizzaStore:
def __init__(self):
pass
def makePizzas(self):
for factory in [IndianPizzaFactory(), USPizzaFactory()]:
self.factory = factory
self.NonVegPizza = self.factory.createNonVegPizza()
self.VegPizza = self.factory.createVegPizza()
# NonVegPizza 依赖于 VegPizza
self.VegPizza.prepare()
self.NonVegPizza.serve(self.VegPizza)
pizza = PizzaStore()
pizza.makePizzas()
'''
Prepare DeluxVeggiePizza
ChickenPizza is served with Chicken on DeluxVeggiePizza
Prepare MexicanVegPizza
HamPizza is served with Ham on MexicanVegPizza
'''

工厂方法和抽象工厂方法的不同

工厂方法 抽象工厂方法
把创造产品的方法暴露给客户 包含一个或多个工厂方法,来创造有关联的产品
子类决定实例化哪一个类 使用合成来委托
工厂方法用来创建一个对象 创造一个有关联的产品族

抽象工厂方法,增加产品族非常难。这要更改AbstractCreator,增加一个createProduct,然后其余的createProduct都要一同更改。
但是增加产品还是很方便的,比如我们增加一个海鲜披萨?
但涉及跨平台的时候,各个操作系统上的软件功能,应用逻辑,UI都大致相似,我们需要的是使用抽象工厂模式屏蔽掉操作系统对应用的影响,调用不同的工厂方法,由不同的产品类去处理与操作系统交互的信息。

文章目录
  1. 1. 简单工厂模式
    1. 1.1. UML图
  2. 2. 工厂方法模式
    1. 2.1. UML图
    2. 2.2. 实现代码
    3. 2.3. 优点
  3. 3. 抽象工厂模式
    1. 3.1. UML图
    2. 3.2. 实现代码
  4. 4. 工厂方法和抽象工厂方法的不同
|