观察者模式 |
当我们希望一个对象的状态发生变化,那么依赖与它的所有对象都能相应变化(获得通知),那么就可以用到Observer模式, 其中的这些依赖对象就是观察者的对象,那个要发生变化的对象就是所谓’观察者 |
# 这个是观察者基类 |
class Subject(object): |
def __init__(self): |
self._observers = [] |
# 添加依赖的对象 |
def attach(self, observer): |
if not observer in self._observers: |
self._observers.append(observer) |
# 取消添加 |
def detach(self, observer): |
try: |
self._observers.remove(observer) |
except ValueError: |
pass |
# 这里只是通知上面注册的依赖对象新的变化 |
def notify(self ... |
访问者模式 |
我觉得Visitor模式是在补修改已有程序结构前提下,通过添加额外的访问者完成对代码功能的拓展 为什么这样用?当你的类层次较多,在某层结构中增加新的方法,要是在基类上面添加或者变更,可能破坏原来的设计, 有兼容问题,所以只在需要的类上面动态添加 |
# 轮子,引擎, 车身这些定义好了都不需要变动 |
class Wheel: |
def __init__(self, name): |
self.name = name |
def accept(self, visitor): |
# 每个visitor是同样的,但是其中的方法是不一样的,比如这里是visitWheel, |
# 然后传入了self,想想?他其实想做什么就能做什么 |
visitor.visitWheel(self) |
class Engine: |
def accept(self ... |
Memento模式 |
备忘录模式一个最好想象的例子:undo! 它对对象的一个状态进行了’快照’, 在你需要的时候恢复原貌。做前端会有一个场景:你设计一个表单,当点击提交会对表单内容 验证,这个时候你就要对用户填写的数据复制下来,当用户填写的不正确或者格式不对等问题, 就可以使用快照数据恢复用户已经填好的,而不是让用户重新来一遍,不是嘛? |
import copy |
def Memento(obj, deep=False): |
# 对你要做快照的对象做快照 |
state = (copy.copy if deep else copy.deepcopy)(obj.__dict__) |
def Restore(): |
obj.__dict__ = state |
return Restore |
class Transaction: |
deep = False |
def __init__(self, *targets ... |
对象池模式 |
在开发中,我们总是用到一些和’池’相关的东西,比如 内存池,连接池,对象池,线程池.. 这里说的对象池其实也就是一定数量已经创建好的对象的集合。为什么要用对象池? 创建对象是要付出代价的(我暂时还没有研究过底层,只说我工作中体会的), 比如pymongo就自带线程池,这样用完就放回到池里再被重用,岂不是节省了创建的花费? |
import Queue |
import types |
import threading |
from contextlib import contextmanager |
class ObjectPool(object): |
def __init__(self, fn_cls, *args, **kwargs): |
super(ObjectPool, self).__init__() |
self.fn_cls = fn_cls |
self._myinit(*args, **kwargs ... |
代理模式 |
Proxy模式是一种常用的设计模式,它主要用来通过一个对象(比如B)给一个对象(比如A) 提供’代理’的方式方式访问。比如一个对象不方便直接引用,代理就在这个对象和访问者之间做了中介 |
class Proxy(object): |
def __init__(self, subject): |
self.__subject = subject |
# 代理其实本质上就是属性的委托 |
def __getattr__(self, name): |
return getattr(self.__subject, name) |
class RGB: |
def __init__(self, red, green, blue): |
self.__red = red |
self.__green ... |
模板方法模式 |
不知道你有没有注意过,我们实现某个业务功能,在不同的对象会有不同的细节实现, 以前说过策略模式, 策略模式是将逻辑封装在一个类(提到的文章中的Duck)中,然后使用委托的方式解决。 模板方法模式的角度是:把不变的框架抽象出来,定义好要传入的细节的接口. 各产品类的公共的行为 会被提出到公共父类,可变的都在这些产品子类中 |
'''http://ginstrom.com/scribbles/2007/10/08/design-patterns-python-style/''' |
# 整个例子我们要根据不同需求处理的内容 |
ingredients = "spam eggs apple" |
line = '-' * 10 |
# 这是被模板方法调用的基础函数 |
def iter_elements(getter, action): |
"""循环处理的骨架""" |
# getter是要迭代的数据,action是要执行的函数 |
for element in getter(): |
action(element) |
print(line) |
def rev_elements ... |
桥接模式 |
这个模式其实就是把产品类的实现和抽象类分离,能够灵活的变化,假如你记得状态模式,它是修改内部属性, 而桥接模式是指定好内部属性,每个产品类指定这个属性被桥接模式类调用,适用于产品类可能经常调整变化,这样还能减少了产品类之间的耦合 |
class Bridge(object): |
def __init__(self): |
self.__implementation = None |
def someFunctionality(self): |
raise NotImplemented() |
class UseCase1(Bridge): |
# 根据初始化参数传入实现的产品类 |
def __init__(self, implementation): |
self.__implementation = implementation |
# 根据传入的产品类的属性打印结果 |
def someFunctionality(self): |
print "UseCase1: ", |
self.__implementation.anotherFunctionality() |
class UseCase2(Bridge): |