例子
我們的網管警示亮燈:是否有警示需要從另一個公司的網管中擷取,我們的介面是:bool IsAlarming,另一個公司的介面是:bool GetAlarm()
定義
適配器模式:將一個類的介面轉換成客戶希望的另外一個介面。適配器模式使得原本由於介面不相容而不能一起工作的那些類可以一起工作。
- 通過繼承進行的適配,叫做類適配器;通過關聯關係進行的適配,叫做對象適配器。二者在實際項目中都會經常用到,由於對象適配器是通過類間的關聯關係進行耦合的,因此在設計時就可以做到比較靈活,而類適配器就只能通過覆寫源角色的方法進行擴充,在實際項目中,對象適配器使用到情境相對較多。
優點
- 1.可以讓兩個沒有任何關係的類在一起運行,只要適配器這個角色能夠搞定他們就成。
- 2.增加了類的透明性。(我們訪問target目標角色,但是具體的實現都委託給了源角色,而這些對高層次模組是透明的,也是它不需要關心的)
- 3.提高了類的複用度(源角色在原有的系統中還是可以正常使用,而在目標角色中也可以充當新的演員)
- 4.靈活性非常好(類似一個靈活的構件,想用就用,不想用就卸載)
注意事項
- 1.在詳細設計階段不要考慮適配器模式,它不是為瞭解決還處在開發階段的問題,而是解決已經投產的項目問題。
- 2.項目一定要遵守依賴倒置原則和裡氏替換原則,否則即使在適合使用適配器的場合下,也會帶來非常大的改造。
上文中提到的兩個原則
裡氏替換原則:
即:一個軟體實體如果使用的是一個父類的話,那麼一定適用於其子類,而且它察覺不出父類對象和子類對象的區別。也就是說,在軟體裡面,把父類都替換成它的子類,程式的行為沒有變化。
依賴倒置原則:
- 1.高層模組不應該依賴於低層模組。兩個都應該依賴抽象。
- 2.抽象不應該依賴細節,細節應該依賴於抽象。
即:要針對介面編程,不要對實現編程。不管高層模組還是低層模組,他們都依賴於抽象,具體一點就是介面或抽象類別,只要介面是穩定的,那麼任何一個的更改都不用擔心其他受到影響,這就使得無論高層模組還是低層模組都可以很容易地被複用。
#include <iostream>using namespace std;class Target{public:virtual void Request(){cout<<"普通的請求"<<endl;}};class Adaptee{public:void SpecificalRequest(){cout<<"特殊請求"<<endl;}};class Adapter :public Target{private:Adaptee* ada;public:virtual void Request(){ada->SpecificalRequest();Target::Request();}Adapter(){ada=new Adaptee();}~Adapter(){delete ada;}};用戶端:int main(){Adapter * ada=new Adapter();ada->Request();delete ada;return 0;}