热门问题
时间线
聊天
视角
適配器模式
来自维基百科,自由的百科全书
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