热门问题
时间线
聊天
视角
适配器模式
来自维基百科,自由的百科全书
Remove ads
在设计模式中,适配器模式(英语:adapter pattern)有时候也称包装样式或者包装(英语:wrapper),将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类能在一起工作,做法是将类自己的接口包裹在一个已存在的类中[1]。
概述
适配器模式是著名的《设计模式:可复用物件导向软体的基础》所收录的二十三个之一[2]。此书描述了如何解决常见的设计问题,以设计出弹性且异重用的物件导向软件(亦即更容易实现、更改、测试、维护和重用的物件)。
结构

在上面的UML类图中,client
类要求target
接口,而不可以直接重复使用adaptee
类,因为它的接口不符合target
接口。client
转而合作于adapter
类,它依据adaptee
而实现了target
接口:
- 对象适配器
object adapter
实现target
接口,总是通过在运行时委托给adaptee
对象(adaptee.specificOperation()
)。 - 类适配器
class adapter
实现target
接口,总是通过在编译时继承自adaptee
类(specificOperation()
)。
在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。


这种适配器模式下,适配器继承自己实现的类(一般多重继承)。


示例
在下面的对象适配器模式例子中,充电器是客户client
,而与它不适配的手机是被适配者adaptee
。为了清晰性可以为适配器采用类名字[被适配者]To[所适配接口]Adapter
,比如例子中的LightningToMicroUsbAdapter
。它应当有一个构造子方法,具有一个adaptee
类变量作为参数。这个参数将被传递给适配器的一个实例成员。在调用clientMethod
的时候,它将访问到这个adaptee
,从而允许访问所需求的adaptee
的数据,并在这个数据上进行运算而生成想要的输出。
interface ILightningPhone {
void recharge();
void useLightning();
}
interface IMicroUsbPhone {
void recharge();
void useMicroUsb();
}
class Iphone implements ILightningPhone {
private boolean connector;
@Override
public void useLightning() {
connector = true;
System.out.println("Lightning connected");
}
@Override
public void recharge() {
if (connector) {
System.out.println("Recharge started");
System.out.println("Recharge finished");
} else {
System.out.println("Connect Lightning first");
}
}
}
class Android implements IMicroUsbPhone {
private boolean connector;
@Override
public void useMicroUsb() {
connector = true;
System.out.println("MicroUsb connected");
}
@Override
public void recharge() {
if (connector) {
System.out.println("Recharge started");
System.out.println("Recharge finished");
} else {
System.out.println("Connect MicroUsb first");
}
}
}
/* exposing the target interface while wrapping source object */
class LightningToMicroUsbAdapter implements IMicroUsbPhone {
private final ILightningPhone lightningPhone;
public LightningToMicroUsbAdapter(ILightningPhone lightningPhone) {
this.lightningPhone = lightningPhone;
}
@Override
public void useMicroUsb() {
System.out.println("MicroUsb connected");
lightningPhone.useLightning();
}
@Override
public void recharge() {
lightningPhone.recharge();
}
}
public class AdapterDemo {
static void rechargeMicroUsbPhone(IMicroUsbPhone phone) {
phone.useMicroUsb();
phone.recharge();
}
static void rechargeLightningPhone(ILightningPhone phone) {
phone.useLightning();
phone.recharge();
}
public static void main(String[] args) {
Android android = new Android();
Iphone iPhone = new Iphone();
System.out.println("Recharging android with MicroUsb");
rechargeMicroUsbPhone(android);
System.out.println("Recharging iPhone with Lightning");
rechargeLightningPhone(iPhone);
System.out.println("Recharging iPhone with MicroUsb");
rechargeMicroUsbPhone(new LightningToMicroUsbAdapter (iPhone));
}
}
输出:
Recharging android with MicroUsb
MicroUsb connected
Recharge started
Recharge finished
Recharging iPhone with Lightning
Lightning connected
Recharge started
Recharge finished
Recharging iPhone with MicroUsb
MicroUsb connected
Lightning connected
Recharge started
Recharge finished
Remove ads
public interface ILightningPhone {
void ConnectLightning();
void Recharge();
}
public interface IUsbPhone {
void ConnectUsb();
void Recharge();
}
public sealed class AndroidPhone : IUsbPhone {
private bool isConnected;
public void ConnectUsb() {
this.isConnected = true;
Console.WriteLine("Android phone connected.");
}
public void Recharge() {
if (this.isConnected) {
Console.WriteLine("Android phone recharging.");
}
else {
Console.WriteLine("Connect the USB cable first.");
}
}
}
public sealed class ApplePhone : ILightningPhone {
private bool isConnected;
public void ConnectLightning() {
this.isConnected = true;
Console.WriteLine("Apple phone connected.");
}
public void Recharge() {
if (this.isConnected) {
Console.WriteLine("Apple phone recharging.");
}
else {
Console.WriteLine("Connect the Lightning cable first.");
}
}
}
public sealed class LightningToUsbAdapter : IUsbPhone {
private readonly ILightningPhone lightningPhone;
private bool isConnected;
public LightningToUsbAdapter(ILightningPhone lightningPhone) {
this.lightningPhone = lightningPhone;
}
public void ConnectUsb() {
this.lightningPhone.ConnectLightning();
}
public void Recharge() {
this.lightningPhone.Recharge();
}
}
public void Main() {
ILightningPhone applePhone = new ApplePhone();
IUsbPhone adapterCable = new LightningToUsbAdapter(applePhone);
adapterCable.ConnectUsb();
adapterCable.Recharge();
}
输出:
Apple phone connected.
Apple phone recharging.
Remove ads
from abc import ABCMeta, abstractmethod
connected_prompt = "{} connected."
connected_first_prompt = "Connect {} first."
recharge_prompt = ["Recharge started.", "Recharge finished."]
class MicroUsbPhone(metaclass=ABCMeta):
@abstractmethod
def recharge(self): pass
@abstractmethod
def use_micro_usb(self): pass
class LightningPhone(metaclass=ABCMeta):
@abstractmethod
def recharge(self): pass
@abstractmethod
def use_lightning(self): pass
class Android(MicroUsbPhone):
def __init__(self):
self.connector = "MicroUSB"
self.connected = False
def use_micro_usb(self):
self.connected = True
print(connected_prompt.format(self.connector))
def recharge(self):
if self.connected:
for state in recharge_prompt:
print(state)
else:
print(connected_first_prompt.format(self.connector))
class IPhone(LightningPhone):
def __init__(self):
self.connector = "Lightning"
self.connected = False
def use_lightning(self):
self.connected = True
print(connected_prompt.format(self.connector))
def recharge(self):
if self.connected:
for state in recharge_prompt:
print(state)
else:
print(connected_first_prompt.format(self.connector))
class LightningToMicroUsbAdapter(MicroUsbPhone):
def __init__(self, phone):
assert isinstance(phone, LightningPhone)
self.connector = "MicroUSB"
self.adaptee = phone
def recharge(self):
self.adaptee.recharge()
def use_micro_usb(self):
print(connected_prompt.format(self.connector))
self.adaptee.use_lightning()
def micro_usb_recharger(phone):
assert isinstance(phone, MicroUsbPhone)
phone.use_micro_usb()
phone.recharge()
def lightning_recharger(phone):
assert isinstance(phone, LightningPhone)
phone.use_lightning()
phone.recharge()
def demo():
android = Android()
iphone = IPhone()
print("Recharging Android with MicroUSB recharger.")
micro_usb_recharger(android)
print()
print("Recharging iPhone with Lightning recharger.")
lightning_recharger(iphone)
print()
print("Recharging iPhone with MicroUSB recharger.")
micro_usb_recharger(LightningToMicroUsbAdapter(iphone))
其执行:
>>> demo()
Recharging Android with MicroUSB recharger.
MicroUSB connected.
Recharge started.
Recharge finished.
Recharging iPhone with Lightning recharger.
Lightning connected.
Recharge started.
Recharge finished.
Recharging iPhone with MicroUSB recharger.
MicroUSB connected.
Lightning connected.
Recharge started.
Recharge finished.
Remove ads
引用
Wikiwand - on
Seamless Wikipedia browsing. On steroids.
Remove ads