设计模式系列-工厂模式
工厂模式,是创建型设计模式,提供了一种创建对象的方式。这种设计模式的主要目的是对客户端不暴露创建逻辑,并通过统一的接口指向新创建的对象。
简单工厂模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Book(object):
@abstractmethod
def publish(self):
pass
class TechnicalBooks(Book):
def publish(self):
return "Python-Book"
class LiteraryBooks(Book):
def publish(self):
return "Black Hole Book"
# 现在假设我们有各种类型的书,那么使用者就必须自己实例化每个类并调用publish方法。这将实现细节暴露了出来,且当类变多时很麻烦
it_books = TechnicalBooks()
ly_books = LiteraryBooks()
这时我们就可以构造一个”简单工厂”把所有实例化的过程封装在里面,把真正实例的类隐藏起来
1
2
3
4
5
6
7
8
9
10
11
12
class SimpleFactory(object):
"""简单工厂"""
@staticmethod
def publish_book(name):
if name == 'technical':
return TechnicalBooks()
elif name == 'literary':
return LiteraryBooks()
it_books2 = SimpleFactory.publish_book('technical')
ly_books2 = SimpleFactory.publish_book('literary')
适用场景:
- 工厂类负责创建的对象比较少:由于创建的对象较少,不会造成工厂方法中的业务逻辑太过复杂。
- 客户端只知道传入工厂类的参数,对于如何创建对象不关心:客户端既不需要关心创建细节,甚至连类名都不需要记住,只需要知道类型所对应的参数。
工厂方法模式
但是,上面这张简单工厂模式不符合开闭原则。如果我们想要新增一种类型的书时,就必须要改变SimpleFactory中的if判断结构。因此出现了工厂方法模式:
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
import abc
# 真正进行实例化的类
class TechnicalBooks(object):
def publish(self):
return "Python-Book"
class LiteraryBooks(object):
def publish(self):
return "Black Hole Book"
# 抽象工厂:先定义抽象类,然后每种类型的书籍都有自己对于的工厂
class AbstractFactory(metaclass=abc.ABCMeta):
@abc.abstractmethod
def publish_book(self):
pass
class TechnicalFactory(AbstractFactory):
"""技术书籍工厂"""
def publish_book(self):
return TechnicalBooks()
class LiteraryFactory(AbstractFactory):
"""文学书籍工厂"""
def publish_book(self):
return LiteraryBooks()
it_books2 = TechnicalFactory().publish_book()
ly_books2 = LiteraryFactory().publish_book()
这样每个工厂就只负责生产自己的产品,避免了在新增产品时需要修改工厂的代码,遵循了”开闭原则”,如果需要新增产品时,只需要增加相应的工厂即可。 适用场景:
- 当系统中拥有的子类很多,并且以后可能还需要不断拓展增加不同的子类时。
- 当设计系统时,还不能明确具体有哪些类时。
- 在工厂方法中,使用者不需要知道具体的产品类名,只需要知道其对应的工厂即可。
抽象工厂
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import abc
# 印刷书籍
class PrintingTechnicalBooks(object):
"""印刷技术书籍"""
def printing(self):
return "Print-Python-Book"
class PrintingLiteraryBooks(object):
"""印刷文学书籍"""
def printing(self):
return "Print Black Hole Book"
# 出版书籍
class TechnicalBooks(object):
"""出版技术书籍"""
def publish(self):
return "Python-Book"
class LiteraryBooks(object):
"""出版文学书籍"""
def publish(self):
return "Black Hole Book"
# 抽象工厂:先定义抽象类,然后每种类型的书籍都有自己对于的工厂
class AbstractFactory(metaclass=abc.ABCMeta):
"""抽象工厂"""
@abc.abstractmethod
def print_book(self):
pass
@abc.abstractmethod
def publish_book(self):
pass
class TechnicalFactory(AbstractFactory):
"""技术书籍工厂"""
def print_book(self):
return PrintingTechnicalBooks()
def publish_book(self):
return TechnicalBooks()
class LiteraryFactory(AbstractFactory):
"""文学书籍工厂"""
def print_book(self):
return PrintingLiteraryBooks()
def publish_book(self):
return LiteraryBooks()
# 实例化工厂对象
it = TechnicalFactory()
ly = LiteraryFactory()
# 印刷书籍
it_print = it.print_book()
ly_print = ly.print_book()
# 出版书籍
it_publish = it.publish_book()
ly_publish = ly.publish_book()
参考: 图解设计模式 https://design-patterns.readthedocs.io/zh_CN/latest/creational_patterns/factory_method.html 设计模式之工厂模式 https://www.cnblogs.com/yssjun/p/11102162.html
This post is licensed under CC BY 4.0 by the author.