设计模式:适配器模式
# 结构型设计模式:
# 其主要用来处理一个系统中不同实体(比如类和对象)之间关系,关注的是提供一种简单的对象组合方式来创造新的功能。
# 当我们希望把一个老组件用于一个新组系统或者把一个新组件应用于老系统中,同时在代码无法修改的,
# 或者说无法访问这些代码时(在实际开发中,旧系统的代码修改后牵一而动全身,很容易引起系统的崩溃。)。
# 这时候,我们可以编写一个额外的代码层,该代码层包含让这两个接口之间能够通信需要进行的所有修改。
# 适配器模式(Adapter Pattern):将一个类的接口转换成为客户希望的另外一个接口.
# Adapter Pattern使得原本由于接口不兼容而不能一起工作的那些类可以一起工作, 因为新的适配器对不兼容的地方进行了包装修复.
# 应用场景:系统数据和行为都正确,但接口不符合时,目的是使控制范围之外的一个原有对象与某个接口匹配,
# 适配器模式主要应用于希望复用一些现存的类,但接口又与复用环境不一致的情况
意图:将一个类的接口转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
角色:
目标接口(Target)
待适配的类(Adaptee)
适配器(Adapter)
两种实现方式:
类适配器:使用多继承
对象适配器:使用组合
适用场景:
你想使用一个已经存在的类,而它的接口不符合你的要求;
你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
(对象适配器)想使用一些已经存在的子类,但不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
类适配器和对象适配器有不同的权衡。
类适配器规则:
使用一个具体的Adapter类对Adaptee和Target进行匹配。结果是当我们想要匹配一个类以及所有他的子类时,类Adapter将不能胜任工作。
使用Adapter可以重定义Adapter的部分行为,因为Adapter是Adaptee的一个子类。
仅仅引入一个对象,并不需要额外的指针以间接得到adaptee.
对象适配器规则:
允许一个Adapter与多个Adaptee -- 即Adaptee本身以及它的所有子类(如果有子类的话)一一同时工作。Adapter也可以一次给所有的Adaptee添加功能。
使得重定义 Adaptee 的行为比较困难。这需要生成Adaptee的子类并且使得 Adapter 引用这个子类而不是引用Adaptee本身。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from abc import abstractmethod, ABCMeta class Payment(metaclass=ABCMeta): @abstractmethod def pay(self, money): raise NotImplementedError class Alipay(Payment): def pay(self, money): print("支付宝支付%s元"%money) class ApplePay(Payment): def pay(self, money): print("苹果支付%s元"%money) #------待适配类------ class WechatPay: def huaqian(self, money): print("微信支付%s元"%money) #------类适配器------ class RealWeChatPay(Payment, WechatPay): def pay(self, money): return self.huaqian(money) #------对象适配器------ class PayAdapter(Payment): def __init__(self, payment): self.payment = payment #类的一个对象 def pay(self, money): return self.payment.huaqian(money) RealWeChatPay().pay(100) #PayAdapter(WechatPay()).pay(1000) 适配器模式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from abc import abstractmethod, ABCMeta class Payment(metaclass=ABCMeta): @abstractmethod def pay(self, money): """支付方法,参数money""" pass #实现Payment接口 class Alipay(Payment): def pay(self, money): print("支付宝支付%s元"%money) class ApplePay(Payment): def pay(self, money): print("苹果支付%s元"%money) class PaymentX(metaclass=ABCMeta): @abstractmethod def zhifu(self, money): """支付方法,参数money""" pass class WechatPay(PaymentX): def zhifu(self, money): print("微信支付%s元"%money) class CreditCardPay(PaymentX): def zhifu(self, money): print("信用卡支付%s元" % money) class PaypalPay(PaymentX): def zhifu(self, money): print("信用卡支付%s元" % money) #类适配器 class RealWechatPay(Payment, WechatPay): def pay(self, money): self.zhifu(money) p = RealWechatPay() p.pay(100) #对象适配器 class RealPay(Payment): def __init__(self, payment_cls): self.__a = payment_cls() def pay(self, money): self.__a.zhifu(money) def test_payment(p): p.pay(100) test_payment(RealPay(CreditCardPay)) 适配器
class Target(object): def request(self): print("普通请求") class Adaptee(object): def specific_request(self): print("特殊请求") # 继承自target, 让它使用新版本的类来实现旧版本的类中的功能, 旧版本代码是不能动的 class Adapter(Target): def __init__(self): self.adaptee = Adaptee() def request(self): self.adaptee.specific_request() if __name__ == "__main__": target = Adapter() target.request()