代碼執行結果如下圖:
代碼說明
l 可以看到,原先的接口中,啟動游戲場景只需要一個參數,就是游戲場景名,而進入新的玩家需要提供玩家ID(新游戲都使用玩家ID而不使用玩家賬戶名)。
l IGame接口就是適配器模式中的目標角色,這是客戶所期待的接口。也是針對老的游戲程序所遵循的接口。
l Lobby類相當於調用方或者客戶,它原先的代碼可能是如下的:
IGame game = new Game();
但是由於接口的改變,現在不能直接實例化游戲類,只能實例化適配器類型。雖然還是需要改動,但是這個改動是很小的,而且完全可以通過用動態加載程序集來消除這種改動。
l GameAdapter類是適配器角色,它是適配器模式的核心,用於把源接口轉變為目標接口。在這裡,我們看到,它實現目標接口。
l Game類型是源角色,或者說是需要適配的對象。或許它也遵循了另外一套接口,不過我們不是很關心這個,因此代碼中也沒有體現。
l 使用了適配器模式後,客戶端代碼沒有做什麼修改。客戶端代碼老老實實的依賴接口,它並沒有錯,如果因此依賴對象的修改而需要大幅度修改就很無辜了,我們在適配器中把本來沒有關聯的兩個接口適配在了一起。我們可以看到,適配器做的不僅僅是換一換方法名,如果源角色和目標角色的差異非常大,那麼適配器需要做很多工作。
何時采用
l 從代碼角度來說, 如果需要調用的類所遵循的接口並不符合系統的要求或者說並不是客戶所期望的,那麼可以考慮使用適配器。
l 從應用角度來說, 如果因為產品遷移、合作模塊的變動,導致雙方一致的接口產生了不一致,或者是希望在兩個關聯不大的類型之間建立一種關系的情況下可以考慮適配器模式。
實現要點
l 適配器模式是否能成功運用的關鍵在於代碼本身是否是基於接口編程的,如果不是的話,那麼適配器無能為力。
l 適配器模式的實現很簡單,基本的思想就是適配器一定是遵循目標接口的。
l 適配器模式的變化比較多,可以通過繼承和組合方式進行適配,適配器可以是一組適配器產品,適配器也可以是抽象類型。
l 適配器模式和Facade的區別是,前者是遵循接口的,後者可以是不遵循接口的,比較靈活。
l 適配器模式和Proxy的區別是,前者是為對象提供不同的接口,或者為對象提供相同接口,並且前者有一點後補的味道,後者是在設計時就會運用的。
注意事項
l 在對兩個無關類進行適配的時候考慮一下適配的代價,一個非常龐大的適配器可能會對系統性能有影響。