文章目录
-
- 从电源适配器谈起
- 实现适配器模式的两种方式
-
- [object adapter](#object adapter)
- [class adapter](#class adapter)
从电源适配器谈起
适配者模式属于结构型设计模式,它的目的是使不兼容的两个对象能够相互工作。
常见的生活例子:去欧美国家旅游时,由于插口和电压不一样,用中国国内的充电器并不能充电,需要借助电源适配器解决问题。
不能工作 phone 220v 国标插口的充电器 110v 电源英标插座接口 电源适配器
为了解决电源适配问题去买了电源适配器
,这个过程中没有改造自己的 220v国标插口的充电器
,也没有找一个国标插座电源插口。
在这个 case 中,220v 国标插口的充电器
和 110v 电源英标插座接口
就是代码中两个类对象,为了让它们能顺利工作,通过引入一个 adapter
来解决兼容问题。
可以看到,adapter 模式由三个部分组成:
Target
目标接口 (110v 电源英标插座接口)adapter
适配器 (电源适配器)adaptee
被适配的接口 (220v 国标插口的充电器)
下面将直接使用以上的英文指代角色
实现适配器模式的两种方式
关于适配器模式的实现分为两种方式:
- object adapter
- class adapter
object adapter
对象适配器,这种方式比较符合我们的经验习惯,先看下它的实现结构图
可以看到这种方式是让 adapter
实现 target
的接口(110v_voltage()
),而这个接口函数的实现实际上是封装了 adaptee.220v_voltage()
。
用代码实现这个案例:
python
class Voltage110V:
def voltage_110v(self):
return "110V"
class Voltage220V:
def voltage_220v(self):
return "220V"
class VoltageAdapter:
def __init__(self, voltage220v: Voltage220V):
self.voltage220v = voltage220v
def voltage_110v(self):
# 这里实现从 220V 转换到 110V
voltage = self.voltage220v.voltage_220v()
return f"{voltage} adapted to 110V"
# 在欧式国家中使用 110V
appliance = Voltage110V()
print(appliance.voltage_110v()) # 输出: 110V
# 中国只支持 220V
china_appliance = Voltage220V()
# 使用电源适配器让中国标准的电器能在欧洲电源接口中充电
adapter = VoltageAdapter(china_appliance)
print(adapter.voltage_110v()) # 输出: 220V adapted to 110V
Question: object adapter
为什么叫对象适配器?
python
adapter = VoltageAdapter(china_appliance)
在这段代码里我们封装了 adaptee
对象(即Voltage220v
实例对象),并用这个对象调用其不兼容的函数。
class adapter
类适配器, 这种实现方式是通过同时继承 adaptee
和 target
,并对其中 target 的接口函数进行重写来达到目的。它和 object adapter
的区别在于使用的时候,它不再需要传入 adaptee
对象,而是可以直接使用(它已经在类的层面做了适配
)。
具体看下面的实现:
python
class Voltage110V:
def voltage_110v(self):
return "110V"
class Voltage220V:
def voltage_220v(self):
return "220V"
class VoltageAdapter(Voltage110V, Voltage220V):
def voltage_110v(self):
# 这里实现从 220V 转换到 110V
voltage = self.voltage_220v()
return f"{voltage} adapted to 110V"
# 使用电源适配器让中国标准的电器能在欧洲电源接口中充电
adapter = VoltageAdapter()
print(adapter.voltage_110v()) # 输出: 220V adapted to 110V
注:上面的实现实际上可以不继承
Voltage220V