iOS_設計模式學習:介面卡模式

BryantHe發表於2018-08-08

最近在學習《Objective-C程式設計之道:iOS設計模式解析》,本文是對介面卡模式的一個分析和例子實現。

例子地址:Bryanthelol/iOS_DesignPattern

標籤:介面適配


一、介面卡模式是什麼

用於連線兩種不同種類的物件,使其毫無問題地協同工作

使得原本由於介面不相容而不能一起工作的那些類可以在一起工作。

介面卡模式主要應用於“希望複用一些現存的類,但是介面又與複用環境要求不一致的情況”,在遺留程式碼複用、類庫遷移等方面非常有用。

二、如何實現介面卡模式

兩種方式實現:

  • 類介面卡
  • 物件介面卡

類介面卡的實現

首先,我們來了解一下OC的一些特性:

Objective-C有協議,作為純粹抽象的一種形式

在Objective-C中,類可以實現協議,同時又繼承超類

因此,達到了多重繼承的效果

然後,可以根據這些語言特性來實現介面卡效果:

  1. 定義一套現在客戶端將要使用的協議

  2. 再用一個介面卡類實現這個協議

  3. 介面卡類繼承自被適配者(也就是那個與現有客戶端不相容的類)

關係圖如下:

iOS_設計模式學習:介面卡模式

Adapter繼承了Target協議的介面method方法,然後過載了method方法。在method方法中,Adapter繼承了Adaptee,但沒有過載specificMethod方法,而是直接呼叫超類specificMethod方法,在Adapter自己的環境下執行。

物件介面卡的實現

物件介面卡不繼承被介面卡,即Adapter不繼承Adaptee。而是用物件組合:Adapter持有一個Adaptee的例項引用。

關係圖如下:

iOS_設計模式學習:介面卡模式

和類介面卡的區別是:

  • Adapter和Adaptee之間的關係從“繼承”變成了“包含”
  • 這種關係下,Adapter需要保持一個對Adaptee的例項引用

在method方法中,Adapter通過adaptee例項,間接呼叫specificMethod方法,在Adapter自己的環境下執行。

類介面卡和物件介面卡的區別對比

  • 類介面卡:

    • 只針對單一的具體的Adaptee類,把Adaptee適配到Target
    • 易於過載Adaptee的行為,因為是通過直接的子類化進行的適配
    • 只有一個Adapter物件,無需額外的指標間接訪問Adaptee
  • 物件介面卡:

    • 可以適配多個Adaptee及其子類
    • 難以過載Adaptee的行為,需要藉助於子類的物件而不是Adaptee本身
    • 需要額外的指標以間接訪問Adaptee並適配其行為

三、用我自己的樣例程式碼講解

在我現在的專案裡,正好有一個例子。

情況是這樣,如圖:

iOS_設計模式學習:介面卡模式

點選了“新增圖片”按鈕後,會彈出下面的“拍照上傳”“從相簿選擇”選項,暫且稱作“彈出框”吧。

現在的問題是,“從相簿選擇”出現的選擇圖片介面,圖片只能被單選:


iOS_設計模式學習:介面卡模式


iOS_設計模式學習:介面卡模式


就像上面兩張圖展示的一樣,選擇一張照片後,就只能點確定了。其實就是使用了iOS自帶的原生相簿,功能不滿足需求。

現在的需求則是:能多選圖片,並且帶有排序,也能單獨編輯一張圖片。就和微信發朋友圈時上傳、編輯圖片一樣。

之後尋找了一個開源的圖片編輯庫IJSPhotoSDK,很好用很強大很好用。

現在的問題是,要把這個庫放進專案裡,但原則是儘量不改變呼叫者(就是上圖,點選“上傳圖片”按鈕的那個檢視類)的程式碼。

這時候介面卡模式就發揮了作用。


介面卡CameraCall類

iOS_設計模式學習:介面卡模式

這個“彈出框”就放在CameraCall這個類,而CameraCall就是我們的主角——介面卡。

回顧一下介面卡的關係類圖(這裡使用物件介面卡實現,因為需要適配多個Adaptee):

iOS_設計模式學習:介面卡模式

CameraCall介面卡符合了這兩個條件:

  • 它有一個CameraCallDelegate協議,供呼叫者簽署然後實現

iOS_設計模式學習:介面卡模式

  • 它持有IJSPhotoSDK圖片編輯庫的例項

iOS_設計模式學習:介面卡模式

因此,IJSPhotoSDK圖片編輯庫的例項只需要呼叫自己的方法,返回圖片資料,然後CameraCall介面卡呼叫協議例項的方法,把資料返回給呼叫者“上傳圖片”按鈕的那個檢視類就可以了。

在檢視類裡實現CameraCallDelegate協議裡的方法:

iOS_設計模式學習:介面卡模式

檢視類不用關心是哪個圖片編輯庫的什麼方法返回的資料,只關心協議方法返回的資料即可。

如果這時候,我們想換一個圖片編輯庫,就可以不改動呼叫者類的程式碼,只在CameraCall介面卡裡換成引入另一個影象編輯器,例項化這個編輯器,然後開始獲取資料的操作就可以了。

可以看到,介面卡模式本質上是把我們想要達成的這個“目的”抽象出來,放入這個叫介面卡的物件中。這個物件進行一系列操作,使得呼叫者只需實現這個介面卡物件即可,無需關心被適配者,就和現實中使用電源介面卡一樣。

最後我們的引入的圖片多選編輯功能就完成了:

iOS_設計模式學習:介面卡模式

iOS_設計模式學習:介面卡模式

相關文章