介面卡模式最接地氣的例項
使用場景:介面卡模式把一個類的介面變換成客戶端所期待的另一種介面,從而使原本因介面不匹配而無法在一起工作的兩個類能夠在一起工作。
引用網上的一個例子:膝上型電腦電源一般用的都是5V電壓,但是我們的家用電是220V,我們要讓筆記本充上電,最好的辦法應該是通過一個工具把220V的電壓轉換成5V,這個工具就是介面卡
好好理解一下設計模式的使用場景比起去記住程式碼是怎樣寫的效果要好很多,說不定你哪天編碼的時候靈光一現用上了,那就是你真正掌握了。
介面卡模式的種類
1. 類介面卡
UML圖(強烈建議大家去了解一下UML圖,它很簡單粗暴的把類與類之間的關係描述的很清楚易懂)

image
我們可以看到,目標介面 Target 就相當於是上面的5V電壓,Adaptee 就是被適配的220V電壓,Adapter 就是介面卡。看程式碼:

image
輸出結果:
<pre style="margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box; word-wrap: break-word !important; color: rgb(51, 51, 51); font-size: 17px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.544px; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">充5V電啦
充220V電啦</pre>
結合上面給點UML圖稍微分析一下:
Adapter類 繼承了 Adaptee220V類 然後實現了介面 Target5V 並實現了目標方法 chong5V(),類介面卡的一個特點就是 Adapter 會去繼承被適配類,這樣介面卡就直接擁有了被適配類中的方法,所以類介面卡的缺點就是不夠靈活,讓我們看一下另外一種介面卡。
2. 物件介面卡

image
UML圖
這裡的 Target 依然是 5V電壓,Adaptee 依然是 220V電壓,比起類介面卡,Adapter 和 Adaptee 的關係從繼承變成了組合,上程式碼:

image
輸出結果:
<pre style="margin: 0px; padding: 0px; max-width: 100%; box-sizing: border-box; word-wrap: break-word !important; color: rgb(51, 51, 51); font-size: 17px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: 0.544px; orphans: 2; text-align: justify; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration-style: initial; text-decoration-color: initial;">充5V電啦
充220V電啦</pre>
這裡我們把 Adaptee220V 通過 Adapter 的構造方法傳入到 Adapter 中,當呼叫 Adapter 的 chong220V()方法 時,實際是呼叫傳進來 Adaptee220V 物件的 chong220V 方法,這樣就會變得很靈活。
專案中的運用
之所以寫這篇關於介面卡設計模式的文章,是因為作者在以前有一次實際開發中,在沒有學習過介面卡模式的前提下,為了解決專案中的一個開發痛點,自己費勁腦筋想出來的一種模式,到現在才知道原來這個叫介面卡模式,在學習了這個設計模式之後更加深入瞭解了一下。接下來,就來演示一下作者在實際工作中使用到的變異形態的物件介面卡模式。
當時開發場景:當時作者開發一個基於POS機的APP,APP要求有列印功能,像訂單列印、日期列印等等。我們知道POS機是有多種型號的,每種型號的POS機會有他們單獨的SDK,也就是說列印方法是不同的!

image
首先,我們每次呼叫列印的時候都會先判斷 POS機 型號,因為型號不對程式肯定會報錯,假如某一天,APP適配的 POS機 型別要增加一款,也就是說我每個判斷 POS機 型號的地方都要多家一個if語句,並且還要把 新POS機型 的列印方法加上去,如果我有5個地方用到了列印,就要加5次,這樣是很痛苦的,別問我為什麼知道。。。經過2次這樣的真實情況發生後,我暴走了,痛定思痛要想個辦法結局,於是有了以下程式碼:

image
每種 POS機 都實現 IPrint 中的列印方法:

image
這裡我把 POS機 型號判斷的程式碼放到了 PrintManager 的構造方法中,每次 **new **出例項時就會去判斷。然後我讓 PrintManager 也實現了IPrint介面,因為我認為專案中的列印管理類必須要擁有這三種列印方法。

image
發現沒,改過之後的程式碼,在不同的呼叫的地方再也不用擔心新增POS機型需要改程式碼了,只需要在 PrintManager 的構造方法中增加一個判斷就好了。要是改成單例:

image
改完之後我哭了。。。我他嗎的是個天才啊。。。後面果然加了多款POS機,但是我再也不痛苦了!看一下我的UML圖:

image
其實,光看UML圖,作者在專案中的這種寫法已經不算是介面卡模式了,因為 Adaptee 已經直接實現了Target中的方法,也就是說根本就不存在不滿足目標介面這個說法了。。不過作者這樣寫完全是自己想出來的,沒有基於任何設計模式,就現在目前的效果來說還是不錯的,通過這篇文章,我對於介面卡模式有了一個清晰的理解,同時也反思了一下我這種寫法,還是很有收穫的。