在這個有沒有物件都要高呼「物件導向」的年代,掌握物件導向會給我們帶來意想不到的方便。學程式設計的小夥伴從開始能寫幾行**實現簡單功能到後來懂得將一些重複的操作組合起來形成乙個「函式」,再到後來將「函式」和屬性組合起來形成乙個「類」。一步步走來,我們在考慮著機器執行**效率的提高的同時也在考慮減輕程式設計師的工作量。 那麼我們今天講到的介面卡模型更著重考慮的是什麼呢?是程式設計師工作量。
什麼時候會用到介面卡模式?
其實最簡單的例子是當我們引用乙個第三方類庫。這個類庫隨著版本的改變,它提供的api也可能會改變。如果很不幸的是,你的應用裡引用的某個api已經發生改變的時候,除了在心中默默地罵「wocao」之外,你還得去硬著頭皮去改大量的**。
難道真的一定要如此嗎?按照套路來說,我會回答「不是的」。我們有介面卡模式啊~~
當介面發生改變時,介面卡模式就派上了用場。
舉個栗子
一開始的和諧
黑棗玩具公司專門生產玩具,生產的玩具不限於狗、貓、獅子,魚等動物。每個玩具都可以進行「張嘴」與「閉嘴」操作,分別呼叫了openmouth與closemouth方法。
在這個時候,我們很容易想到可以第一定義乙個抽象類toy,甚至是介面toy,這些問題不大,其他的類去繼承父類,實現父類的方法。一片和諧,信心向榮。
平衡的破壞
為了擴大業務,現在黑棗玩具公司與紅棗遙控公司合作,紅棗遙控公司可以使用遙控裝置對動物進行嘴巴控制。不過紅棗遙控公司的遙控裝置是呼叫的動物的domouthopen及domouthclose方法。黑棗玩具公司的程式設計師現在必須要做的是對toy系列類進行公升級改造,使toy能呼叫domouthopen及domouthclose方法。
考慮實現的方法時,我們很直接地想到,你需要的話我再在我的父類子類裡給你新增這麼兩個方法就好啦。當你一次又一次在父類子類裡面重複新增著這兩個方法的時候,總會想著如此重複的工作,難道不能解決麼?當有數百個子類的時候,程式設計師會改瘋的。程式設計師往往比的是誰在不影響效率的時候更會「偷懶」。這樣做下去程式設計師會覺得自己很傻。(其實我經常當這樣的傻子)
abstract更加煩躁class
toyclass dog extends
toy
public
function
closemouth()
//增加的方法
public
function
domouthopen()
//增加的方法
public
function
domouthclose()
}class cat extends
toy
public
function
closemouth()
//增加的方法
public
function
domouthopen()
//增加的方法
public
function
domouthclose()
}
程式設計師剛剛碼完**,喝了口水,突然間另乙個訊息傳來。
黑棗玩具公司也要與綠棗遙控公司合作,因為綠棗遙控公司遙控裝置更便宜穩定。不過綠棗遙控公司的遙控裝置是呼叫的動物的opermouth(typ
e)方法
來實現嘴
巴控制。
如果type)方法來實現嘴巴控制。如果
type為0則「閉嘴」,反之張嘴。
這下好了,程式設計師又得對toy及其子類進行公升級,使toy能呼叫opermouth()方法。擱誰都不淡定了。
abstract在這個時候,程式設計師必須要動腦子想辦法了,就算自己勤快,萬一哪天紫棗青棗黃棗山棗這些遙控公司全來的時候,忽略自己不斷增多的工作量不說,這個toy類可是越來越大,總有一天程式設計師不崩潰,系統也會崩潰。class
toy
class dog extends
toy
public
function
closemouth()
public
function
domouthopen()
public
function
domouthclose()
public
function operatemouth($type = 0)
else
} }
class cat extends
toy
public
function
closemouth()
public
function
domouthopen()
public
function
domouthclose()
public
function operatemouth($type = 0)
else
} }
問題在出在**呢?
像上面那樣編寫**,**實現違反了「開-閉」原則,乙個軟體實體應當對擴充套件開放,對修改關閉。即在設計乙個模組的時候,應當使這個模組可以在不被修改的前提下被擴充套件。也就是說每個屍體都是乙個小王國,你讓我參與你的事情這個可以,但你不能修改我的內部,除非我的內部**確實可以優化。
在這種想法下,我們懂得了如何去用繼承,如何利用多型,甚至如何實現「高內聚,低耦合」。
回到這個問題,我們現在面臨這麼乙個問題,新的介面方法我要實現,舊的介面(toy抽象類)也不能動,那麼總得有個解決方法吧。那就是引入乙個新的類--我們本文的主角--介面卡。 介面卡要完成的功能很明確,引用現有介面的方法實現新的介面的方法。更像它名字描述的那樣,你的介面不改的話,我就利用現有介面和你對接一下吧。
到此,解決方法已經呼之欲出了,下面貼上**。
<?php最後的結果就是,toy類及其子類在不改變自身的情況下,通過介面卡實現了不同的介面。abstract
class
toy
class dog extends
toy
public
function
closemouth()
}
class cat extends
toy
public
function
closemouth()
}//目標角色:紅棗遙控公司
inte***ce
redtarget
//目標角色:綠棗遙控公司及
inte***ce
greentarget
//類介面卡角色:紅棗遙控公司
class redadapter implements
redtarget
//委派呼叫adaptee的samplemethod1方法
public
function
domouthopen()
public
function
domouthclose()
}
//類介面卡角色:綠棗遙控公司
class greenadapter implements
greentarget
//委派呼叫adaptee:greentarget的operatemouth方法
public
function operatemouth($type = 0)
else
} }class
testdriver
} $test = new
testdriver();
$test->run();
最後總結
將乙個類的介面轉換成客戶希望的另外乙個介面,使用原本不相容的而不能在一起工作的那些類可以在一起工作.
介面卡模式核心思想:把對某些相似的類的操作轉化為乙個統一的「介面」(這裡是比喻的說話)--介面卡,或者比喻為乙個「介面」,統一或遮蔽了那些類的細節。介面卡模式還構造了一種「機制」,使「適配」的類可以很容易的增減,而不用修改與介面卡互動的**,符合「減少**間耦合」的設計原則。
php設計模式之介面卡模式
借鑑 適用性 原理 將要用到的角色分為以下幾種 target最早實現的介面,adaptee改善之後的介面,adapter對target和adapter進行適配,client呼叫介面 類介面卡模式 author mtg 目標角色 version 1.0 class target 目標點 public ...
PHP設計模式之介面卡模式
php設計模式之介面卡模式 1 介面卡模式的概念 介面卡設計模式只是將某個物件的介面適配為另乙個物件所期待的介面。2 uml靜態模型 3 單例模式舉例 今天從網路上爬了一些資料,爬下來的內容如下 所示,該內容在另一頁面直接顯示,這裡的爬蟲 就不寫了,只寫乙個模擬的效果。address 山東威海農副產...
PHP設計模式之 介面卡模式
介面卡要完成的功能很明確,引用現有介面的方法實現新的介面的方法。你的介面不改的話,我就利用現有介面和你對接一下吧。開 閉 原則,乙個軟體實體應當對擴充套件開放,對修改關閉 class toy describe 原有的介面 author nick abstract class toy class do...