Swift設計模式 – 適配器模式 (Adapter Pattern)


你和我都是熱衷於學習的工程師,我們經常閱讀各種書籍或文章,常常因為一本書寫的實在太好,於是又買了其中提到的其他書籍,我們深深的感受到知識帶來的精神上飽足感。

我們又同時熱愛分享,常常在自己的Blog上撰寫讀書心得,在社群網站上分享文章,在生活中又經常與好友推薦與分享自己所閱讀到的好書

而同時我們又是熱愛分享的工程師,我們經常撰寫Blog,遊走於各種社交平台,到處分享所見所得,還常常舉辦workshop活動,我們不只是在獲取知識上得到滿足,我們還在分享的過程中得到了成就感。

由於我們在Stone City中的活躍,似乎工程圈的人都認識了我們,所以當Stone City市長打算建造一間城市中最大的圖書館時,也找到了我們。


市長打算打造一個城市中最大間的圖書館,取名叫Stone Library,他希望這間圖書館在初期能夠有最基本的兩種書籍查詢功能,按照書名、分類來查找。

當然,這樣的目標對我們兩個來說還是蠻容易達成的,在接下這個挑戰之後,我們身上產生了一股熱流,連續通宵了七天之後就寫好了。

基本的書籍查詢功能

首先,我們建立一個StoneLibrary.swift並且定義了一本書最基本的兩個Property分別是name以及category,並且規定資料來源必須要實現books來獲取所有的書籍,以及通過name和category來進行search的方法。

StoneLibrary.swift

接著我們建立StoneLibraryDB,所有的書籍放在books中,並且提供兩個方法用(searchByName, searchByCategory)來查詢書籍,你和我都很清楚,因為這兩個search方法的實現方式是一樣的,所以我們將其中的方法獨立出來,放在search方法中。

接著,我們整理好了ComputerScience和Fruit兩類書籍,並且規定他們要遵循StoneLibraryDB協議。

StoneLibraryDB.swift

提供一個對外的查詢工具,工具中規範了兩種SearchType,並且可以在初始化時加入書籍資料StoneLibraryDB,可以通過books來獲取所有的書籍,通過search方法來查找書籍。

StoneLibrarySearchTool.swift

在我們完成後拿去給Stone City的市長做測試:

我們調用了測試的code:

看到下面的運行結果,看來是成功了,市長表示非常高興,他已經看到了升遷的希望:D

不過Stone City的市長是非常有野心的,他想要打造一個圖書館平台,希望市民能夠通過這一個平台來搜尋所有圖書館的書籍,任何人想要借書都可以通過這個平台,當市民借閱一本書籍時,這本書就會搬運到距離這個市民最近的圖書館,聽起來超方便的對不對?!

然而每一間圖書館的系統都是不一樣的,要把他們都融入自己的系統中真的是一件不容易的事情,而且有一些舊系統,在還沒有全盤了解之前,都不知道是不是可以改動source code….


整合第一間Old Library

OldLibrary是我們需要整合的第一間圖書館,他的歷史非常悠久,至今為止已經服務過幾代人了,剛和這間圖書館的Devloper聯繫,他們串了一段Source Code過來。

並且在email中表示,目前他們只剩下一位負責維護的Developer,如果需要整合,目前來看是沒有時間去修改Code的。

看到下面的source code,目前來說,我們光是繼續維護開發Stone Library的系統就已經忙得不可開交,這下子該怎麼整合呢?


適配器模式(Adapter Pattern)

當現有的系統需要繼承一個具有類似功能的新組件,而該組件沒有提供通用接口,並且無法修改改組件時,這時候就可以用上適配器了。

  • 優點:將無法修改source code的組件集成到現有的項目中。在使用第三方框架或者利用另一個項目所輸出的數據時,通常會遇到組件之間的兼容問題。
  • 何時應該避免使用:如果可以修改所要集成的組件的SourceCode或者可以直接將該組件提供的Data直接遷移到現有的應用中的話。(比如我們其實可以直接將OldLibrary中的資料copy到StoneLibrary中)

從長遠來看,數據遷移是個不錯的方式,但有時卻很難快速的完成,但現實生活中常常碰到的是找不到原有的開發工程師配合,又或者沒有足夠的人力投入,所以有時候直接使用適配器模式可以取得一些短期的效益。

 

適配器模式就很像上面這個轉接頭,我們通過製作一個轉接頭,就可以在不改造設備內部結構的情況下直接使用該設備了。


實現OldLibraryAdapter

創建適配器的幾個步驟:

  • 創建一個OldLibraryAdapter,並且讓它遵從LibraryDataSource協議
  • Adapter向OldLibrary發送請求,OldLibrary處理請求內容,將結果返回給Adapter
  • Adapter將OldLibrary返回的結果,轉換成StoneLibrary所需要的內容

我們創建了OldLibraryAdapter.swift並且讓他遵循StoneLibrarydataSource協議,其中我們在實現books的獲取,searchByName以及SearchByCategory的過程,實際上是調用OldLibrary的一些方法,在獲得需要的資料以後將Data轉換成StoneLibrary所使用的格式(Book)在返回內容。

OldLibraryAdapter.swift


最後的測試

這時候我們提供給Stone City的市長測試時,他可以不用了解Old Library的實現情況,而直接使用我們的OldLibraryAdapter就可以了!

輸出結果

市長放煙火啦~


最後,在欣賞完煙火以後,可以通過傳送門到Github上看看適配器模式的例子

 

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *