Adapter 模式 - Class Adapter


Adapter模式的另一種作法是Class Adapter模式,這個模式主要運用多重繼承,讓Adapter繼承想要引入的Adaptee類別以獲得其介面,並繼承Target以獲得想要使用之介面。
Adapter


這個模式主要適用於支援多重繼承之介面,Adaptee可能不只一個,如C++、Python,如果是Python,一個實現的方式如下:
class Adaptee1:
def doAction1(self):
print("action 1")

class Adaptee2:
def doAction2(self):
print("action 2")

class Adaptor(Adaptee1, Adaptee2):
def doRequest(self): # doRequest 是期望之介面
self.doAction1()
self.doAction2()
print("request")

adaptor = Adaptor()
adaptor.doRequest()

對於支援多重繼承的語言來說,這種方式自然且簡潔,但對於只支援單一繼承的語言則無法直接套用,例如在Java中若要採用Class Adapter,必須作點修改,一方面繼承Adaptee,一方面實作Target的介面:
Adapter


若使用Java的話,程式碼的實作是這樣: 
public class Adapter extends Adaptee implements Target {
    public void request() {
        specificRequest();
    }
}

不 過,顯然的有些限制,Adapter仍舊只能繼承一個Adaptee,若有多個Adaptee想要引進,這個修改就仍不適合,再著在單一繼承下 is a 的關係更為強烈,採用這種方式引入Adaptee,意謂著您的Adapter是一種Adaptee,所以Class Adapter在Java中適用的場合較少,事實上,若僅是在這個修改中引用Adaptee的公開介面,會比較建議改用Object Adapter,因為Object Adapter模式比較有彈性,例如,您可以在Adapter上加上個setter,以隨時可以抽換Adaptee,您也可以在一個Object Adapter中擁有多個Adaptee實例。

也許您會在Java中使用Class Adapter的時機,在於Adaptee的公開介面無法組合出您想要的功能時,您會希望繼承Adaptee後直接使用其內部資料或方法來實作Target的介面,不過這顯然前題是,那些您想觸及的內部資料或方法必須是protected的,依舊有所限制。