责任链模式
内容:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。 角色 抽象处理者(Handler) 具体处理者(ConcreteHandler) 客户端(Client)
from abc import ABCMeta, abstractmethodclass Handler ( metaclass= ABCMeta) : @abstractmethod def handle_leave ( self, day) : pass class GeneralManager ( Handler) : def handle_leave ( self, day) : if day < 10 : print ( f"总经理准假 { day} 天" ) else : print ( "你还是辞职吧" ) class DepartmentManager ( Handler) : def __init__ ( self) : self. next = GeneralManager( ) def handle_leave ( self, day) : if day < 7 : print ( f"部门经理准假 { day} 天" ) else : print ( "部门经理职权不够,交给总经理处理" ) self. next . handle_leave( day) class ProjectDirector ( Handler) : def __init__ ( self) : self. next = DepartmentManager( ) def handle_leave ( self, day) : if day < 3 : print ( f"项目主管准假 { day} 天" ) else : print ( "项目主管职权不够,交给部门经理处理" ) self. next . handle_leave( day)
day = 4
h = ProjectDirector( )
h. handle_leave( day)
项目主管职权不够,交给部门经理处理
部门经理准假4天
适用场景: 有多个对象可以处理一个请求,哪个对象处理由运行时决定 在不明确接收者的情况下,向多个对象中的一个提交一个请求 优点: 降低耦合度:一个对象无需知道是其他哪一个对象处理其请求
观察者模式
内容:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。观察者模式又称“发布-订阅”模式 角色 抽象主题(Subject) 具体主题(ConcreteSubject)————发布者 抽象观察者(Observer) 具体观察者(ConcreteObserver)————订阅者
from abc import ABCMeta, abstractmethod
class Observer ( metaclass= ABCMeta) : @abstractmethod def update ( self, notice) : pass
class Staff ( Observer) : def __init__ ( self, name) : self. name = nameself. company_info = None def update ( self, notice) : self. company_info = notice. company_info
class Notice : def __init__ ( self) : self. observers = [ ] def attach ( self, observer) : self. observers. append( observer) def detach ( self, observer) : if observer in self. observers: self. observers. remove( observer) def notify ( self) : for obs in self. observers: obs. update( self)
class StaffNotice ( Notice) : def __init__ ( self, company_info= None ) : super ( ) . __init__( ) self. __company_info = company_info@property def company_info ( self) : return self. __company_info@company_info. setter def company_info ( self, new_info) : self. __company_info = new_infoself. notify( )
notice = StaffNotice( '初始信息' )
obj1 = Staff( '张三' )
obj2 = Staff( '李四' ) notice. attach( obj1)
notice. attach( obj2) notice. company_info = '明天放假'
print ( obj1. company_info)
明天放假
适用场景: 当一个抽象模型有两方面,其中一个方面依赖于另一个方面。将这两者封装在独立对象中以使它们可以各自独立地改变和复用。 当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。 优点:
策略模式
内容:定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。 角色: 抽象策略(Strategy) 具体策略(ConcreteStrategy) 多上下文(Context)
from abc import ABCMeta, abstractmethodclass Strategy ( metaclass= ABCMeta) : @abstractmethod def execute ( self, data) : pass class FastStrategy ( Strategy) : def execute ( self, data) : print ( f"采用快速策略处理 { data} " ) class SlowStrategy ( Strategy) : def execute ( self, data) : print ( f"采用慢速策略处理 { data} " ) class Context : def __init__ ( self, strategy, data) : self. data = dataself. strategy = strategydef set_strategy ( self, strategy) : self. strategy = strategydef do_strategy ( self) : self. strategy. execute( self. data)
data = 'data...'
s1 = FastStrategy( )
context = Context( s1, data)
context. do_strategy( ) s2 = SlowStrategy( )
context. set_strategy( s2)
context. do_strategy( )
采用快速策略处理data...
采用慢速策略处理data...
优点: 定义了一系列可重用的算法和行为 消除了一些条件语句 可以提供相同行为的不同实现 缺点:
模板方法模式
内容:定义一个操作中的算法的骨架,而将一些步聚延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 角色 抽象类(AbstractClass):定义抽象的原子操作(钩子操作);实现一个模板方法作为算法的骨架。 具体类(ConcreteClass):实现原子操作
from abc import ABCMeta, abstractmethod
from time import sleepclass Window ( metaclass= ABCMeta) : @abstractmethod def start ( self) : pass @abstractmethod def repaint ( self) : pass @abstractmethod def stop ( self) : pass def run ( self) : self. start( ) while True : try : self. repaint( ) sleep( 1 ) except KeyboardInterrupt: print ( '终止' ) break self. stop( ) class MyWindow ( Window) : def __init__ ( self, msg) : self. msg = msgdef start ( self) : print ( '窗口开始运行' ) def repaint ( self) : print ( self. msg) def stop ( self) : print ( '窗口停止运行' ) MyWindow( 'Hello, World!' ) . run( )
窗口开始运行
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
Hello, World!
终止
窗口停止运行
适用场景: 一次性实现一个算法的不变的部分 各个子类中的公共行为应该被提取出来并集中到一个公共父类中以避免代码重复 控制子类扩展