天天看點

Adapter模式Adapter模式

Adapter模式

引言

生活中有很多Adapter的例子。比方說,你買了一款舒适、手感極佳的鍵盤,它是P/S接口的,然而你的新式電腦已經淘汰了P/S接口,隻提供USB接口。此時,為了能夠使用這款鍵盤,就需要一個轉接頭,它的一頭是P/S接口的,用來連接配接鍵盤;另一頭是USB的,用來連接配接電腦。類似這樣的轉接頭就充當一個Adapter的作用。類似的例子還有電源的三相/兩相 轉接頭等等。

 Adapter模式應該是設計模式中一個輕量級的模式,實作起來也比較簡單,有時候不經意中,你可能就已經實作了一個Adapter模式,隻是自己沒有發現而已。本文将通過一個範例介紹 Adapter模式。

Shape範例

很多程式設計的書籍中都喜歡使用一個Shape作為範例講述面向對象中的繼承,盡管這裡我們講述的是Adapter模式,但是并不妨礙我們也使用這個Shape的例子。考慮下面一幅關系圖:

Adapter模式Adapter模式

在這幅圖中,Shape抽象類定義了Draw()方法,用于在螢幕上繪制圖形,Square和Circle繼承了Shape類,并實作了Draw()方法。另一個與Shape相關聯的類Window,它的Initialize()方法接受一個Shape類型的參數,并調用其Draw()方法(實際中還可能進行其他操作,這裡的關鍵是方法的簽名隻接受一個Shape類型的參數)。

public void Initialize(Shape s)

現在考慮這樣一種情況:假如我們從第三方獲得了另一個類XTriangle,而它并沒有Draw()方法,隻有一個完成同樣功能的Display()方法。很顯然,這個類也不會繼承自Shape基類,我們也無法對其進行修改。此時。如果我們想讓客戶程式Window類使用XTriangle類,就不得不再重載一個Initialize()方法,讓它接受一個XTriangle類型的參數。但這是治标不治本的方法,因為可能有很多類似Window的類,它們都隻接受Shape類型,對每一處都進行修改顯然是不切實際的。此時,通常的辦法是建立一個包裝(Wrapper)類,讓這個包裝類繼承自Shape,同時讓它含有一個對XTriangle的引用,并且将Draw()方法的實作委托給XTriangle.Display()去完成。我們将這個包裝類命名為Triangle,而這種模式或者解決類似問題的方法,就稱為Adapter模式。注意在很多情況下我們會将Triangle命名為TriangleAdapter,但這裡命名為Triangle會更清晰一些,但它仍是一個Adapter。下面是類圖:

Adapter模式Adapter模式

接下來我們看下來看一下Triangle的實作:

public class Triangle : Shape {

    private XTriangle triangle;

    public Triangle(XTriangle triangle) {

        this.triangle = triangle;

    }

    public override void Draw() {

        triangle.Display();

}

OK,這樣就實作了Adapter模式,它的正式定義是:

将一個類(XTriangle)的接口轉換為用戶端(Window)所期待的另一接口(Shape)。Adpater能夠讓各個類之間互相協作,而不受不相容接口的影響。

總結

這篇文章通過一個簡短的範例示範了Adatper模式,通過建立一個包裝類,解決了在引入第三方類時接口不相容的問題。感謝閱讀,希望這篇文章能給你帶來幫助。

繼續閱讀