Python实现设计模式之抽象工厂

python实现设计模式中的抽象工厂模式

再讲到抽象工厂模式之前,先简要谈一谈自己对于简单工厂和工厂模式的理解。


一、简单工厂

简单工厂:简单工厂只有一个工厂存在,让子类决定实例化哪一个类,通常接住if判断条件,实例化不同的类。

优点:思想简单易行,通过用户来控制实例化的类,适用于简单的场景

缺点:违背了软件工程中的开闭原则,当增添额外的条件时候,需要修改工厂类。

例子:

1
2
3
4
5
6
7
8
9
10
11
12

def factory(self, request, password, verification_code, way):
"""set factory to manage all functions in this class"""
# 如果增添了产品,需要修改该工厂类
func_list = {
'email': 'register_email',
'phone': 'register_phone'
}
func = func_list.pop(way)
result = getattr(self, func) # use reflection based on str to get function
return result(request, password, verification_code)


二、工厂模式

工厂模式:相对于简单工厂来说,将逻辑判断分割到不同的子类中进行实现,一定程度上,降低了耦合性。假如某一个工厂中生产多个商品,这样的话,工厂模式就可以将这些商品分成不同的子类,然后再封装一层接口,实例化这些子类。此时工厂模式并不需要提供实例化子类的逻辑,而将这些交给公用接口去实现。

优点:一定程度上降低了耦合度。在针对多个商品,一家公司作为一个工厂的情况下遵循了开闭原则,无须修改工厂类。

缺点:在针对一维模型下适用,但是如果存在多家公司,多种商品的二维模型下,想要扩展多个工厂的话,就要修改工厂类代码,此时违反了开闭原则。

例子:

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

class ShapeFactory(object):
'''工厂类'''

def getShape(self):
return self.shape_name

class Circle(ShapeFactory):

def __init__(self):
self.shape_name = "Circle"
def draw(self):
print('draw circle')

class Rectangle(ShapeFactory):
def __init__(self):
self.shape_name = "Retangle"

def draw(self):
print('draw Rectangle')


class ShapeInterfaceFactory(object):
'''接口基类'''
def create(self):
'''把要创建的工厂对象装配进来'''
raise NotImplementedError

class ShapeCircle(ShapeInterfaceFactory):
def create(self):
return Circle()


class ShapeRectangle(ShapeInterfaceFactory):
def create(self):
return Rectangle()

# 属于同一个工厂
shape_interface = ShapeCircle()
obj = shape_interface.create()
obj.getShape()
obj.draw()

shape_interface2 = ShapeRectangle()
obj2 = shape_interface2.create()



三、抽象工厂模式

抽象工厂模式:抽象工厂模式相较于工厂模式来说,主要区别在于抽象工厂模式可以实现多工厂结构,也就是多家公司,而工厂模式
针对的单工厂结构。

优点:有效的降低了耦合度,分离接口和实现,切换工厂方便,选择不同的工厂。

缺点:存在一定的限制性,比如一家公司的产品,只能由这家公司生产,同时如果将给某一家公司中添加新的产品,仍需要修改工厂类。

可以适用于自定义支付系统,自定义不同app的日志系统等

例子

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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

# -*- coding: utf-8 -*-
# @Time : 2020/5/9 8:50
# @Author : 司云中
# @File : loggings.py
# @Software: PyCharm

import abc
import logging


class Abstract_logger_factory(metaclass=abc.ABCMeta):
"""抽象工厂"""

@abc.abstractmethod
def common_logger(self):
pass

@abc.abstractmethod
def specific_logger(self):
pass


class Consumer_factory(Abstract_logger_factory):
"""the factory with consumer"""

def common_logger(self):
return django_logger().create_logger()

def specific_logger(self):
return Consumer().create_logger()


class Shopper_factory(Abstract_logger_factory):
"""the factory with shopper"""

def common_logger(self):
return django_logger().create_logger()

def specific_logger(self):
return Shopper().create_logger()


class App_base(metaclass=abc.ABCMeta):
"""abstact app"""

@abc.abstractmethod
def create_logger(self):
pass


class django_logger(App_base):
"""最基本的INFO日志"""

def __init__(self, logger_name='django'):
self.logger = logging.getLogger(logger_name)

def create_logger(self):
return self.logger


class Consumer(App_base):
"""the logger come from consumer"""
def __init__(self, logger_name='consumer_'):
self.logger = logging.getLogger(logger_name)

def create_logger(self):
return self.logger


class Shopper(App_base):
"""the logger come from shopper"""

def __init__(self, logger_name='shopper_'):
self.logger = logging.getLogger(logger_name)

def create_logger(self):
return self.logger


class Interface_logger:
"""expose interface"""

def __init__(self, factory):
self.common_logger = factory.common_logger()
self.specific_logger = factory.specific_logger()

def get_common_logger(self):
return self.common_logger

def get_specific_logger(self):
return self.specific_logger