python 设计模式之适配器模式

1. 适配器模式

将一个类的接口转换成客户希望的另一个接口。Adapter 模式使得原本由于接口不兼容而不能在一起工作的那些类可以一起工作。

上面这段话有以下几个关键信息要掌握:

  1. 接口不兼容
  2. 转换
  3. 一起工作

接口不兼容,为啥不重新写一个兼容的接口呢?这个问题其实就道出了设计模式的精髓所在,工程师琢磨出各种设计模式的目的之一就是尽可能的减少对已经编写好的代码进行修改。将一个类的接口转换成客户希望的另一个接口,这句话表名,这个类已经有一个接口了,可是我不想直接修改它,这是重点,一旦修改了,那么单元测试要重新做,之前用这个接口的地方都要重新测试,甚至可能出现之前的代码发生不兼容的情况,越改就越乱。

那么,能不能写一个新的接口呢,原来的接口,咱不动了还不行么?记住,你抛开设计模式设计程序永远是可行的,而之所以不这样做,是因为虽然原来的那个接口没有变化,但这个类有变化呀,多出来一个新的接口。忘记了我们的目的了么,尽可能少的减少对已经编写好的代码进行修改,如果这些代码是别人编写的,你有足够的自信修改别的源码么?

既不能修改,也不想新增,怎么办呢,答案是转换,谁来转换,适配器来转换。适配器把原本不兼容的接口转换成了可以直接使用的接口,从而让两个类可以在一起工作。

2. 举例子

生活中就有非常贴切的例子可以用来解释什么是适配器,比如手机的充电器,它就是一个很好的适配器。想要给手机充电,就要给它接入电流,但问题是家用电都是220V 电压,手机能接受的电压是5V的,如果直接在插座和手机之间扯根线,手机直接就爆了。

插座和手机就是两个不能在一起工作的类,前者输出220V 电压的电,后者只能接收5V电压的电,这时就需要一个手机充电器来将220V电压的电转换成5V电压的电。

前面这个例子顺便带出了适配器模式的三个重要概念:

  1. Adaptee, 被适配的内容,插座就是Adaptee,它能输出220V 电压的电
  2. Target, 适配为的内容,我们的目标是一个可以输出5V电压的类
  3. Adapter, 适配器,把 Adeptee 适配成 Target

适配器解决的是接口不一致的问题,但不能解决功能不一致的问题,既功能原本就是有的,只是两边对不上,插座可以输出电流,手机也可以充电,但是一个输出的是220V ,一个只能接收5V,这种情况适配器就可以大显身手了。

3. 编码实现

from abc import ABC, abstractmethod


class Power:
    def __init__(self):
        self.output = 220

    def get_output(self):
        return self.output


class Transto5V(ABC):
    @abstractmethod
    def transto5V(self):
        pass


class Adapter(Transto5V, Power):
    def transto5V(self):
        output = super(Adapter, self).get_output()
        return output // 44


class Phone:
    def charge(self, adapter):
        if adapter.transto5V() == 5:
            print("手机正在充电")
        else:
            print("电压过高,无法充电")


if __name__ == "__main__":
    adapter = Adapter()
    phone = Phone()
    phone.charge(adapter)

Phone类原本无法与Power类一起工作,我们加入了适配器类Adapter, 它是Power的子类,同时也是Transto5V类的子类且必须实现transto5V方法,这个方法在Phone和Power类之间构建起一个联系的桥梁,最终Power可以像Phone类供电。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案