目录
- 一、桥接模式
- 问题描述
- 问题分析
- 模式定义
- 代码实现
- 二、职责链模式
- 问题描述
- 问题分析
- 模式定义
- 代码实现
- 三、中介模式
- 问题描述
- 问题分析
- 模式定义
- 优缺点
- 代码实现
- 四、命令模式(后补)
- 问题描述
- 问题分析
- 模式定义
- 代码实现
- 五、享元模式(后补)
- 六、解释器模式(后补)
- 七、访问者模式(后补)
一、桥接模式
问题描述
对于不同品牌的手机,软件基本无法兼容。因此如果手机需要增加软件,就需要针对不同品牌的手机分别实现软件功能。
问题分析
对象的继承关系是在编译时就定义好了,所以无法在运行时改变从父类继承的实现。子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。
模式定义
合成/聚合复用原则(CARP),尽量使用合成/聚合,尽量不要使用类继承。
聚合表示一种弱的’拥有’关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分;合成则是一种强的’拥有’关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。
合成/聚合复用原则的好处是,优先使用对象的合成/聚合将有助于你保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。
桥接模式(Bridge),将抽象部分与它的实现部分分离,使它们都可以独立地变化。
代码实现
# 手机软件抽象类
class HandsetSoft(object):
def run(self):
pass
# 手机软件具体类
class HandsetGame(HandsetSoft):
def run(self):
print("运行手机游戏")
class HandsetAddressList(HandsetSoft):
def run(self):
print("运行手机通讯录")
class HandsetMP3(HandsetSoft):
def run(self):
print("运行手机MP3播放")
# 手机品牌抽象类
class HandsetBrand(object):
soft = None
def set_handset_soft(self, soft):
self.soft = soft
def run(self):
pass
# 手机品牌具体类
class HandsetBrandN(HandsetBrand):
def run(self):
self.soft.run()
class HandsetBrandM(HandsetBrand):
def run(self):
self.soft.run()
class HandsetBrandS(HandsetBrand):
def run(self):
self.soft.run()
if __name__ == '__main__':
ab = HandsetBrandN()
ab.set_handset_soft(HandsetGame())
ab.run()
ab.set_handset_soft(HandsetAddressList())
ab.run()
ab = HandsetBrandM()
ab.set_handset_soft(HandsetGame())
ab.run()
ab.set_handset_soft(HandsetAddressList())
ab.run()
二、职责链模式
问题描述
你把今天你向经理申请,经理没权利,然后向总监上报,总监也没权限,向总经理上报的事,写成代码来看看吧,注意哦,不一定是加薪,还有可能是请假申请等。
问题分析
可能会增加管理类别,那就意味着这里容易变化,我想把这些公司管理者的类别分别做成管理者的子类,这就可以利用多态性来化解分支带来的僵化。
模式定义
职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
好处:
- 当客户提交一个请求时,请求是沿链传递直至有一个ConcreteHandler对象负责处理它。
- 接收者和发送者都没有对方的明确信息,且链中的对象自己也并不知道链的结构。结果是职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接受者的引用[DP]。这也就大大降低了耦合度了。
代码实现
class Request(object):
__requestType = None
__requestContent = None
__number = None
def get_requestType(self):
return self.__requestType
def set_requestType(self, value):
self.__requestType = value
def get_requestContent(self):
return self.__requestContent
def set_requestContent(self, value):
self.__requestContent = value
def get_number(self):
return self.__number
def set_number(self, value):
self.__number = value
requestType = property(get_requestType, set_requestType)
requestContent = property(get_requestContent, set_requestContent)
number = property(get_number, set_number)
# 管理者
class Manager(object):
superior = None
def __init__(self, name):
self.name = name
def set_superior(self, superior):
self.superior = superior
def request_applications(self, request: Request):
pass
# 经理类
class CommonManager(Manager):
def __init__(self, name):
super().__init__(name)
def request_applications(self, request: Request):
if (request.requestType == "请假") and (request.number <= 2):
print(f'{self.name}:{request.requestContent} 数量{request.number} 被批准')
else:
if self.superior != None:
self.superior.request_applications(request)
# 总监
class Majordomo(Manager):
def __init__(self, name):
super().__init__(name)
def request_applications(self, request: Request):
if (request.requestType == "请假") and (request.number <= 5):
print(f'{self.name}:{request.requestContent} 数量{request.number} 被批准')
else:
if self.superior != None:
self.superior.request_applications(request)
# 总经理
class GeneralManager(Manager):
def __init__(self, name):
super().__init__(name)
def request_applications(self, request: Request):
if (request.requestType == "请假"):
print(f'{self.name}:{request.requestContent} 数量{request.number} 被批准')
elif (request.requestType == "加薪") and (request.number <= 500):
print(f'{self.name}:{request.requestContent} 数量{request.number} 被批准')
elif (request.requestType == "加薪") and (request.number > 500):
print(f'{self.name}:{request.requestContent} 数量{request.number} 再说吧')
if __name__ == '__main__':
jinli = CommonManager('金利')
zongjian = Majordomo('宗剑')
zhongjingli = GeneralManager('钟精励')
jinli.set_superior(zongjian)
zongjian.set_superior(zhongjingli)
request1 = Request()
request1.requestType = "请假"
request1.requestContent = "小菜请假"
request1.number = 1
jinli.request_applications(request1)
request2 = Request()
request2.requestType = "请假"
request2.requestContent = "小菜请假"
request2.number = 4
jinli.request_applications(request2)
request3 = Request()
request3.requestType = "加薪"
request3.requestContent = "小菜请求加薪"
request3.number = 500
jinli.request_applications(request3)
request4 = Request()
request4.requestType = "加薪"
request4.requestContent = "小菜请求加薪"
request4.number = 1000
jinli.request_applications(request4)
三、中介模式
问题描述
需求是美国和伊拉克之间的对话都是通过联合国安理会作为中介来完成。
问题分析
美国和伊拉克都是国家,有一个国家抽象类和 两 个 具 体 国 家 类 就 可 以 了 。 但 ’ 联 合 国 ’ 到 底 是 Mediator 还 是 ConcreteMediator呢?
这要取决于未来是否有可能扩展中介者对象,比如你觉得联合国除了安理会,还有没有可能有其他机构存在呢?
联合国的机构还有如国际劳工组织、教科文组织、世界卫生组织、世界贸易组织等,很多的,所以Mediator应该是’联合国机构’,而’安理会’是一个具体的中介者。
模式定义
中介者模式(Mediator),用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了’多对多’交互复杂的对象群时,不要急于使用中介者模式,而要先反思你的系统在设计上是不是合理。
中介者模式一般应用于一组对象以定义良好但是复杂的方式进行通信的场合,比如刚才得到的窗体Form对象或Web页面aspx,以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合。
优缺点
优点:
- 中介者模式的优点首先是Mediator的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和Mediator;
- 由于把对象如何协作进行了抽象,将中介作为一个独立的概念并将其封装在一个对象中,这样关注的对象就从对象各自本身的行为转移到它们之间的交互上来,也就是站在一个更宏观的角度去看待系统。
缺点:
- 具 体 中 介 者 类 ConcreteMediator 会 因 为 ConcreteColleague越来越多,而变得非常复杂,反而不容易维护了。
- 由于ConcreteMediator控制了集中化,于是就把交互复杂性变为中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague都复杂。
代码实现
# 联合国机构类
class UnitedNations(object):
def declare(self,message,colleague):
pass
# 国家类
class Country(object):
def __init__(self,mediator:UnitedNations):
self.mediator = mediator
# 美国类
class USA(Country):
def __init__(self,mediator:UnitedNations):
super().__init__(mediator)
def declare(self,message):
self.mediator.declare(message,self)
def get_message(self,message):
print("美国获得对方信息:"+message)
# 伊拉克类
class Iraq(Country):
def __init__(self,mediator:UnitedNations):
super().__init__(mediator)
def declare(self,message):
self.mediator.declare(message,self)
def get_message(self,message):
print("伊拉克获得对方信息:"+message)
# 联合国安理会
class UnitedNationSecurityCouncil(UnitedNations):
__colleague1 = None
__colleague2 = None
def get_colleague1(self):
return self.__colleague1
def get_colleague2(self):
return self.__colleague2
def set_colleague1(self,value):
self.__colleague1 = value
def set_colleague2(self,value):
self.__colleague2 = value
colleague1 = property(get_colleague1,set_colleague1)
colleague2 = property(get_colleague2,set_colleague2)
def declare(self, message, colleague:Country):
if colleague == self.colleague1:
self.colleague2.get_message(message)
else:
self.colleague1.get_message(message)
if __name__ == '__main__':
UNSC = UnitedNationSecurityCouncil()
c1 = USA(UNSC)
c2 = Iraq(UNSC)
UNSC.colleague1 = c1
UNSC.colleague2 = c2
c1.declare("不准研制核武器,否则要发动战争!")
c2.declare("我们没有核武器,也不怕侵略。")