热门问题
时间线
聊天
视角

配接器模式

来自维基百科,自由的百科全书

适配器模式
Remove ads

設計模式中,配接器模式(英語:adapter pattern),有時候也稱為包裝器(英語:wrapper),它將一個類別的介面轉接成客戶所預期的介面。配接器使得因介面不相容而不能在一起工作的類別能在一起工作,做法是將要被適配的已存在的類別實例或介面,包裹在預期的目標介面的實現之中[1]

Thumb
對象配接器模式的UML類別圖,這裏的配接器單一繼承並實現了目標介面,被適配者聚集英語Object composition#Aggregation至配接器,反過來說配接器可導航關聯英語Association (object-oriented programming)至被適配者。

概述

適配器模式是著名的《設計模式:可復用物件導向軟件的基礎》所收錄的二十三個模式之一[2]。此書描述了如何解決常見的設計問題,以設計出彈性且異重用的物件導向軟件(亦即更容易實現、更改、測試、維護和重用的物件)。

結構

Thumb
配接器模式的樣例UML類別圖。[3]

在上面的UML類別圖中,client類別要求target介面,而不可以直接重複使用adaptee類別,因為它的介面不符合target介面。client轉而合作於adapter類別,它依據adaptee而實現了target介面:

  • 對象配接器object adapter實現target介面,總是通過在執行時委託給adaptee對象(adaptee.specificOperation())。
  • 類別配接器class adapter實現target介面,總是通過在編譯時繼承自adaptee類別(specificOperation())。

對象配接器模式

在這種配接器模式中,配接器容納一個它包裹的類別的實例。在這種情況下,配接器會呼叫被包裹對象的實例。

Thumb
統一建模語言(UML)表示的對象配接器模式,這裏省略了配接器所繼承並實現的目標介面Target

類別配接器模式

這種配接器模式使用多個多型介面,實現或者繼承它所預期的目標介面,並且繼承事先存在的被適配介面。預期的目標介面典型的被建立為純介面類別,特別是在不支援類別的多重繼承的程式語言比如Java(JDK 1.8以前)之中[1]

Thumb
用統一建模語言(UML)表示的類別配接器模式,這裏省略了配接器所實現的目標介面Target

範例

在下面的對象配接器模式例子中,充電器是客戶client,而與它不適配的手機是被適配者adaptee。為了清晰性可以為配接器採用類別名字[被适配者]To[目标接口]Adapter,比如例子中的LightningToMicroUsbAdapter。它應當有一個構造子方法,具有一個adaptee類變量作為參數。這個參數將被傳遞給配接器的一個實例成員。在呼叫clientMethod的時候,它將訪問到這個adaptee,從而允許訪問所需求的adaptee的數據,並在這個數據上進行運算而生成想要的輸出。

Java

下面是Java例子:

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

C#

下面是C#例子:

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

Python

下面是Python例子:

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.connected = False
        self.adaptee = phone
    def use_micro_usb(self):
        self.connected = True
        print(connected_prompt.format(self.connector))
        self.adaptee.use_lightning()
    def recharge(self):
        if self.connected:
            self.adaptee.recharge()
        else:
            print(connected_first_prompt.format(self.connector))

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

參照

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads