一、Python创建型设计模式
1、工厂模式(Factory):解决对象创建问题
2、构造模式(Builder):控制复杂对象的创建
3、原型模式(Prototype):通过原型的克隆创建新的实例
4、单例模式(Brog/Singleton):一个类只能创建同一个对象
5、对象池模式(Pool):预先分配同一类型的一组实例
6、惰性计算模式(Lazy Evaluaion):延迟计算(Python的property)
(1)工厂模式
解决对象创建问题,解耦对象的创建和使用,包括工厂方法和抽象工厂
# 工厂方法的一个例子
class Dog:
def speak(self):
print("WangWang!")
class Cat:
def speak(self):
print("MiaoMiao!")
def animal(speak_type):
if speak_type == 'Dog':
return Dog()
elif speak_type == 'Cat':
return Cat()
(2)构造模式
用来控制复杂对象的构造,创建和表示分离。比如买电脑,工厂模式直接给你电脑而构造模式则允许自己自定义电脑的配置,组装后给你
# 构造模式的一个例子
class Computer:
def __init__(self, serial_number):
self.serial = serial_number
self.memory = None
self.hdd = None
self.gpu = None
def __str__(self):
info = ('Memory: {}GB'.format(self.memory),
'Hard Disk: {}GB'.format(self.hdd),
'Graphics Card: {}'.format(self.gpu))
return '\n'.join(info)
class ComputerBuilder:
def __init__(self):
self.computer = Computer('XXXXXXXX')
def configure_memory(self, amount):
self.computer.memory = amount
def configure_hdd(self, amount):
self.computer.hdd = amount
def configure_gpu(self, gpu_model):
self.computer.gpu = gpu_model
class HardwareEngineer:
def __init__(self):
self.builder = None
def construct_computer(self, memory, hdd, gpu):
self.builder = ComputerBuilder()
[step for step in (self.builder.configure_memory(memory),
self.builder.configure_hdd(hdd),
self.builder.configure_gpu(gpu))]
@property
def computer(self):
return self.builder.computer
engineer = HardwareEngineer()
engineer.construct_computer(hdd=1024, memory=32, gpu='GeForce GTX 2080 Ti')
computer = engineer.computer
print(computer)
(3)原型模式
通过克隆原型来创建新的实例,可以使用相同的原型,通过修改部分属性来创建新的示例,用途:对于一些创建实例开销比较高的地方可以使用原型模式
(4)单例模式
一个类创建出来的对象是同一个,例如:Python模块就是单例的,多次导入只会导入一次。可以使用共享同一个实例来创建单例模式
# 单例模式
class Singleton:
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_instance'):
_instance = super().__new__(cls, *args, **kwargs)
cls._instance = _instance
return cls._instance
二、结构型设计模式
1、装饰器模式(Decorater):无需子类化扩展对象功能
2、代理模式(Proxy):把一个对象的操作代理到另一个对象
3、适配器模式(Adapter):通过一个间接层适配统一接口
4、外观模式(Facade):简化复杂对象的访问问题
5、享元模式(Flyweight):通过对象复用(池)改善资源利用,比如连接池
6、Model-View-Controller(MVC):解耦显示逻辑和业务逻辑
(1)代理模式
把对象的操作代理到另一个对象,这里可以用到Stack/Queue,把操作代理到deque。
# 代理模式 —— Stack
from collections import deque
class Stack(object):
def __init__(self):
self._deque = deque()
def push(self, value):
return self._deque.append(value)
def pop(self):
return self._deque.pop()
def empty(self):
return len(self._deque) == 0
(2)适配器模式
把不同的对象的接口适配到同一个接口,当需要不同的对象统一接口的时候可以使用适配器模式
class Dog(object):
def __init__(self):
self.name = "Dog"
def bark(self):
return "woof"
class Cat(object):
def __init__(self):
self.name = "Cat"
def miao(self):
return "miao"
class Adapter:
def __init__(self, obj, **adapted_methods):
self.obj = obj
self.__dict__.update(adapted_methods)
def __getattr__(self, attr):
return getattr(self.obj, attr)
objects = []
dog = Dog()
objects.append(Adapter(dog, make_noise=dog.bark))
cat = Cat()
objects.append(Adapter(cat, make_noise=cat.bark))
for obj in objects:
print("A {0} goes {1}".format(obj.name, obj.make_noise()))
三、行为型模式
1、迭代器模式(Iterator):通过统一的接口迭代对象
2、观察者模式(Observer):对象发生改变的时候,观察者执行相应的动作
3、策略模式(Strategy):针对不同规模输入使用不同的策略
(1)迭代器模式
Python内置对迭代器模式的支持,可以用for遍历各种Iterable的数据类型,不可迭代对象需要用(__next__和__iter__)实现迭代器,可以迭代的对象只使用__iter__
# 迭代器模式 —— 可以迭代的Stack
from collections import deque
class Stack(object):
def __init__(self):
self._deque = deque()
def push(self, value):
return self._deque.append(value)
def pop(self):
return self._deque.pop()
def empty(self):
return len(self._deque) == 0
def __iter__(self):
res = []
for i in self._deque:
res.append(i)
for i in reversed(res):
yield i
(2)观察者模式
发布订阅最为常见,发布订阅用于解耦逻辑,可以通过回调等方式实现,当条件发生时可以使用相应的回调函数
# 发布订阅模式
class Publisher:
def __init__(self):
self.observers = []
def add(self, observer):
if observer not in self.observers:
self.observers.append(observer)
else:
print('Failed to add : {}'.format(observer))
def remove(self, observer):
try:
self.observers.remove(observer)
except:
print('Failed to remove : {}'.format(observer))
def notify(self):
[o.notify_by(self) for o in self.observers]
class Formatter(Publisher):
def __init__(self, name):
super().__init__()
self.name = name
self._data = 0
@property
def data(self):
return self._data
@data.setter
def data(self, new_value):
self._data = int(new_value)
self.notify()
class BinaryFormatter:
def notify_by(self, publisher):
print("{} : {} has now bin data = {}".format(
type(self).__name__,
publisher.name,
bin(publisher.data)))
(3)策略模式
根据不同输入采用不同的策略,对外暴露统一的接口,内部采用不同的策略计算
# 策略模式
class Order:
def __init__(self, price,discount_strategy=None):
self.price = price
self.discount_strategy = discount_strategy
def price_after_discount(self):
if self.discount_strategy:
discount = self.discount_strategy(self)
else:
discount = 0
return self.price - discount
def __repr__(self):
fmt = "<Price: {}, price after discount: {}>"
return fmt.format(self.price, self.price_after_discount())