Python设计模式笔记

Creatial Patterns

Abstract Factory

抽象工厂模式: 提供一个接口创建对象,但不需要指定他们真实的类,适用于创建抽象对象依赖不同的配置、平台选择等

Python实现
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
class PetShop:
def __init__(self, animal_factory=None):
self.pet_factory = animal_factory

def show_pet(self):
pet = self.pet_factory()
print("We have a lovely {}".format(pet))
print("It says {}".format(pet.speak()))

class Dog:
def speak(self):
return "woof"

def __str__(self):
return "Dog"

class Cat:
def speak(self):
return "maomao"

def __str__(self):
return "Cat"

if __name__ == "__main__":
cat_shop = PetShop(cat)
cat_shop.show_pet()

Factory

工厂模式: 一个函数创建其他的对象

Python实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class DevConfig:
DEBUG = False

class ProdConfig:
DEBUG = True

def get_debug(config='dev'):
config = {
"dev": DevConfig,
"prod": ProdConfig
}

return config[config].DEBUG


if __name__ == "__main__":
get_debug('dev')

Borg

Borg: 多个实例之间分享相同的状态

Python实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Borg:
__shared_state = {} # 类中的私有变量

def __init__(self):
self.__dict__ = self.__shared_state
self.state = "Init"

def __str__(self):
return self.state

class YourBorg(Borg):
pass

if __name__ == "__main__":
b1 = Borg()
b2 = Borg()
b1.state = 'hhh'
b2.state = 'wcg'
print(b1, b2) # wcg wcg

Builder

构造模式: 解耦一个复杂对象的创建和表示,通常抽象

Python实现
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
class Building:
def __init__(self):
self.build_floor()
self.build_size()

def build_floor(self):
raise NotImplementedError

def build_size(self):
raise NotImplementedError

def __repr__(self):
return 'Floor: {0.floor} | Size: {0.size}'.format(self)

class House(Building):
def build_floor(self):
self.floor = 'One'

def build_size(self):
self.size = 'Big'

class Flat(Building):
def build_floor(self):
self.floor = 'More than One'

def build_size(self):
self.size = 'Smail'

if __name__ == "__main__":
house = House()
flat = Flat()

Lazy_evaluation

惰性求值: 初始化的时候不计算,调用的时候才计算

Python实现
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
import functools

class lazy_property:
def __init__(self, func):
self.func = func
functools.update_wrapper(self, func)

def __get__(self, obj, type_):
if obj is None:
return self
val = self.func(obj)
obj.__dict__[self.func.__name__] = val
return val

def lazy_property2(fn):
attr = '_lazy_' + fn.__name__

@property
def _lazy_property(self):
if not hasattr(self, attr):
setattr(self, attr, fn(self))
return getattr(self, attr)

return _lazy_property

class Person:
def __init__(self, name, occupation):
self.name = name
self.occupation = occupation
self.call_count = 0

@lazy_property
def relatives(self):
relatives = "Many relatives"
return relatives

@lazy_property2
def parents(self):
self.call_count += 1
return "Father and mother"

if __name__ == "__main__":
Jhon = Person('Jhon', 'Coder')
Json.name # Jhon
Json.occupation # Coder
Json.__dict__.items() # [('name': 'Json', 'occupation': 'Coder', 'call_count': 0)]
Json.relatives # 'Many relatives'
Json.__dict__.items() # [('relatives': 'Many relatives')]
Json.parents # 'Father and mother'
Json.__dict__.items() # [('_lazy__parents': 'Father and mother' ...)]
Json.parents # 'Father and mother'
Json.call_count # 1 call_count不会变

Pool

池: 保存相同的一组实例

Python实现
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
class ObjectPool(object):
def __init__(self, queue, auto_get=False):
self._queue = queue
self.item = self._queue.get() if auto_get else None

def __enter__(self): # 上下文
if self.item is None:
self.item = self._queue.get()
return self.item

def __exit__(self, type, value, traceback):
if self.item is not None:
self._queue.put(self.item)
self.item = None

def __del__(self):
if self.item is not None:
self._queue.put(self.item)
self.item = None

if __name__ == "__main__":
import queue

sample_queue = queue.Queue()
sample_queue.put('yam')
with ObjectPool(sample_queue) as obj:
print('Inside with: {}'.format(obj))
print('Outside with: {}'.format(sample_queue.get()))

# Inside with: yam
# Outside with: yam

Prototype

原型: 通过克隆原型创建实例,减少类

Python实现
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
class Prototype:
value = 'dafault'

def clone(self, **attrs):
obj = self.__class__
obj.__dict__.update(attrs)
return obj

class PrototypeDispatcher:
def __init__(self):
self._objects = {}

def get_objects(self):
return self._objects

def register_object(self, name, obj):
self._objects[name] = obj

def unregister_object(self, name):
del self._objects[name]

def main():
dispatcher = PrototypeDispatcher()
prototype = Prototype()

d = prototype.clone()
a = prototype.clone(value='a-value', category='a')
b = prototype.clone(value='b-value', is_checked=True)
dispatcher.register_object('default', d)
dispatcher.register_object('objecta', a)
dispatcher.register_object('objectb', b)
print([{n: p.value} for n, p in dispatcher.get_objects().items()])
# [{'default': 'default'}, {'objecta': 'a-value'}, {'objectb': 'b-value'}]

Structural Patterns

3-tier

3-tier: 分离演示,应用程序处理和数据管理,一层层封装

Python实现
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
class Data:
products = {
'milk': {'price': 1.50, 'quantity': 10},
'eggs': {'price': 0.20, 'quantity': 100},
'cheese': {'price': 2.00, 'quantity': 10},
}

def __get__(self, obj, klas):
return {'products': self.products}

class BussinessLogic:
data = Data()

def product_list(self):
return self.data['products'].keys()

def product_information(self, product):
return self.data['products'].get(product, None)

class UI:
def __init__(self):
self.business_logic = BussinessLogic()

def get_product_list(self):
for product in self.business_logic.product_list():
print(product)

def get_prouduct_informatin(self, product):
pass

def main():
ui = UI()
ui.get_product_list()
ui.get_prouduct_informatin('eggs')

adapter

适配器: 通过引入间接层来实现不兼容接口的适配,可以用继承,也可以用dict属性

Python实现
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
class Dog:
def __init__(self):
self.name = 'dog'

def bark(self):
return 'wangwang'

class Cat:
def __init__(self):
self.name = 'cat'

def meow(self):
return 'maomao'

class Car:
def __init__(self):
self.name = name

def make_noise(self):
return 'dididi'

class Adapter:
def __init__(self, obj, **adapted_methods):
self.obj = obj
self.__dict__.update(adapted_methods)

def __getattr__(self, attr): # 从obj获取
return getattr(self.obj, attr)

def original_dict(self):
return self.obj.__dict__

def main():
dog = Dog()
dog.__dict__ # {'name': 'Dog'}
a = Adapter(dog, make_noise=dog.bark)
a.__dict__ # {'obj': <__main__.Dog at xxx>, 'make_noise': <bound method Dog.bark of <__main__.Dog at xxx>}
a.bark == a.make_noise # True
a.make_noise() # 'wangwang'

bridge

桥模式: 将抽象和实现分离

Python实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class DrawingApi1:
def draw_circle(self, x, y, radius):
print('Api1.circle at {}:{} radius {}'.format(x, y, radius))

class DrawingApi2:
def draw_circle(self, x, y, radius):
print('Api2.circle at {}:{} radius {}'.format(x, y, radius))

class CircleShape:
def __init__(self, x, y, radius, drawing_api):
self._x = x
self._y = y
self._radius = radius
self._drawing_api = drawing_api

def draw(self):
self._drawing_api.draw_circle(self._x, self._y, self._radius)

def scale(self, pct):
self._radius *= pct

def main():
shape = CircleShape(1, 2, 3, DrawingApi1())
shape.draw()

composite

综合模式:让客户端统一处理单个对象和组合

Python实现
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
class Graphic:
def render(self):
raise NotImplementedError("You should implement this")

class CompositeGraphic(Graphic):
def __init__(self):
self.graphics = []

def render(self):
for graphic in self.graphics:
graphic.render()

def add(self, graphic):
self.graphics.append(graphic)

def remove(self, graphic):
self.graphics.remove(graphic)

class Ellipse(Graphic):
def __init__(self, name):
self.name = name

def render(self):
print("Ellipse: {}".format(self.name))

def main():
pass

decorator

装饰器模式:不改变实例,动态给对象增加新的功能

Python实现
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
class TextTag:
def __init__(self, text):
self._text = text

def render(self):
return self._text

class BoldWrapper(TextTag):
def __init__(self, wrapped):
self._wrapped = wrapped

def redner(self):
return '<b>{}</b>'.format(self._wrapped.render())

class ItalicWrapper(TextTag):
def __init__(self, wrapped):
self._wrapped = wrapped

def render(self):
return '<i>{}</i>'.format(self._wrapped.render())

if __name__ == '__main__':
simple_hello = TextTag('hello, world')
special_hello = ItalicWrapper(BoldWrapper(simple_hello))
simple_hello.render() # hello, world
special_hello.render() # <i><b>hello, world</b></i>

facade

facade: 提供一个简单统一的接口来隐藏复杂的系统

Python实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class CPU:
def freeze(self):
pass
def jump(self):
pass
def execute(self):
pass

class Memory:
def load(self):
pass

class Computer:
def __init__(self):
self.cpu = CPU()
self.memory = Memory()

def start(self):
self.cpu.freeze()
self.memory.load()
self.cpu.jump()
self.cpu.execute()

参考

https://github.com/faif/python-patterns
https://python-web-guide.readthedocs.io/zh/latest/design/design.html
https://github.com/itswcg/Books/blob/master/Head%20First%20%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F.pdf

----------本文完,感谢您的阅读----------