您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)php中適配器模式的原理是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對相關(guān)知識(shí)有一定的了解。
什么時(shí)候會(huì)用到適配器模式?
其實(shí)最簡單的例子是當(dāng)我們引用一個(gè)第三方類庫。這個(gè)類庫隨著版本的改變,它提供的API也可能會(huì)改變。如果很不幸的是,你的應(yīng)用里引用的某個(gè)API已經(jīng)發(fā)生改變的時(shí)候,除了在心中默默地罵“wocao”之外,你還得去硬著頭皮去改大量的代碼。
難道真的一定要如此嗎?按照套路來說,我會(huì)回答“不是的”。我們有適配器模式啊~~
當(dāng)接口發(fā)生改變時(shí),適配器模式就派上了用場。
舉個(gè)栗子
如果通過上面的簡單描述,你都能懂,那在下只能佩服你的領(lǐng)悟能力超群了。一般人一定還是不知所云。為了方便理解,我引用一位博友的例子。原文地址。
一開始的和諧
黑棗玩具公司專門生產(chǎn)玩具,生產(chǎn)的玩具不限于狗、貓、獅子,魚等動(dòng)物。每個(gè)玩具都可以進(jìn)行“張嘴”與“閉嘴”操作,分別調(diào)用了openMouth與closeMouth方法。
在這個(gè)時(shí)候,我們很容易想到可以第一定義一個(gè)抽象類Toy,甚至是接口Toy,這些問題不大,其他的類去繼承父類,實(shí)現(xiàn)父類的方法。一片和諧,信心向榮。
平衡的破壞
為了擴(kuò)大業(yè)務(wù),現(xiàn)在黑棗玩具公司與紅棗遙控公司合作,紅棗遙控公司可以使用遙控設(shè)備對動(dòng)物進(jìn)行嘴巴控制。不過紅棗遙控公司的遙控設(shè)備是調(diào)用的動(dòng)物的doMouthOpen及doMouthClose方法。黑棗玩具公司的程序員現(xiàn)在必須要做的是對Toy系列類進(jìn)行升級(jí)改造,使Toy能調(diào)用doMouthOpen及doMouthClose方法。
考慮實(shí)現(xiàn)的方法時(shí),我們很直接地想到,你需要的話我再在我的父類子類里給你添加這么兩個(gè)方法就好啦。當(dāng)你一次又一次在父類子類里面重復(fù)添加著這兩個(gè)方法的時(shí)候,總會(huì)想著如此重復(fù)的工作,難道不能解決么?當(dāng)有數(shù)百個(gè)子類的時(shí)候,程序員會(huì)改瘋的。程序員往往比的是誰在不影響效率的時(shí)候更會(huì)“偷懶”。這樣做下去程序員會(huì)覺得自己很傻。(其實(shí)我經(jīng)常當(dāng)這樣的傻子)
abstract class Toy { public abstract function openMouth(); public abstract function closeMouth(); //為紅棗遙控公司控制接口增加doMouthOpen方法 public abstract function doMouthOpen(); //為紅棗遙控公司控制接口增加doMouthClose方法 public abstract function doMouthClose(); } class Dog extends Toy { public function openMouth() { echo "Dog open Mouth\n"; } public function closeMouth() { echo "Dog open Mouth\n"; } //增加的方法 public function doMouthOpen() { $this->doMouthOpen(); } //增加的方法 public function doMouthClose() { $this->closeMouth(); } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth\n"; } public function closeMouth() { echo "Cat open Mouth\n"; } //增加的方法 public function doMouthOpen() { $this->doMouthOpen(); } //增加的方法 public function doMouthClose() { $this->closeMouth(); } }
更加煩躁
程序員剛剛碼完代碼,喝了口水,突然間另一個(gè)消息傳來。
黑棗玩具公司也要與綠棗遙控公司合作,因?yàn)榫G棗遙控公司遙控設(shè)備更便宜穩(wěn)定。不過綠棗遙控公司的遙控設(shè)備是調(diào)用的動(dòng)物的operMouth(type)方法來實(shí)現(xiàn)嘴巴控制。如果type)方法來實(shí)現(xiàn)嘴巴控制。如果type為0則“閉嘴”,反之張嘴。
這下好了,程序員又得對Toy及其子類進(jìn)行升級(jí),使Toy能調(diào)用operMouth()方法。擱誰都不淡定了。
abstract class Toy { public abstract function openMouth(); public abstract function closeMouth(); public abstract function doMouthOpen(); public abstract function doMouthClose(); //為綠棗遙控公司控制接口增加doMouthClose方法 public abstract function operateMouth($type = 0); } class Dog extends Toy { public function openMouth() { echo "Dog open Mouth\n"; } public function closeMouth() { echo "Dog open Mouth\n"; } public function doMouthOpen() { $this->doMouthOpen(); } public function doMouthClose() { $this->closeMouth(); } public function operateMouth($type = 0) { if ($type == 0) { $this->closeMouth(); } else { $this->operateMouth(); } } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth\n"; } public function closeMouth() { echo "Cat open Mouth\n"; } public function doMouthOpen() { $this->doMouthOpen(); } public function doMouthClose() { $this->closeMouth(); } public function operateMouth($type = 0) { if ($type == 0) { $this->closeMouth(); } else { $this->operateMouth(); } } }
在這個(gè)時(shí)候,程序員必須要?jiǎng)幽X子想辦法了,就算自己勤快,萬一哪天紫棗青棗黃棗山棗這些遙控公司全來的時(shí)候,忽略自己不斷增多的工作量不說,這個(gè)Toy類可是越來越大,總有一天程序員不崩潰,系統(tǒng)也會(huì)崩潰。
問題在出在哪里呢?
像上面那樣編寫代碼,代碼實(shí)現(xiàn)違反了“開-閉”原則,一個(gè)軟件實(shí)體應(yīng)當(dāng)對擴(kuò)展開放,對修改關(guān)閉。即在設(shè)計(jì)一個(gè)模塊的時(shí)候,應(yīng)當(dāng)使這個(gè)模塊可以在不被修改的前提下被擴(kuò)展。也就是說每個(gè)尸體都是一個(gè)小王國,你讓我參與你的事情這個(gè)可以,但你不能修改我的內(nèi)部,除非我的內(nèi)部代碼確實(shí)可以優(yōu)化。
在這種想法下,我們懂得了如何去用繼承,如何利用多態(tài),甚至如何實(shí)現(xiàn)“高內(nèi)聚,低耦合”。
回到這個(gè)問題,我們現(xiàn)在面臨這么一個(gè)問題,新的接口方法我要實(shí)現(xiàn),舊的接口(Toy抽象類)也不能動(dòng),那么總得有個(gè)解決方法吧。那就是引入一個(gè)新的類--我們本文的主角--適配器。 適配器要完成的功能很明確,引用現(xiàn)有接口的方法實(shí)現(xiàn)新的接口的方法。更像它名字描述的那樣,你的接口不改的話,我就利用現(xiàn)有接口和你對接一下吧。
到此,解決方法已經(jīng)呼之欲出了,下面貼上代碼。
<?php abstract class Toy { public abstract function openMouth(); public abstract function closeMouth(); } class Dog extends Toy { public function openMouth() { echo "Dog open Mouth\n"; } public function closeMouth() { echo "Dog close Mouth\n"; } } class Cat extends Toy { public function openMouth() { echo "Cat open Mouth\n"; } public function closeMouth() { echo "Cat close Mouth\n"; } } //目標(biāo)角色:紅棗遙控公司 interface RedTarget { public function doMouthOpen(); public function doMouthClose(); } //目標(biāo)角色:綠棗遙控公司及 interface GreenTarget { public function operateMouth($type = 0); } //類適配器角色:紅棗遙控公司 class RedAdapter implements RedTarget { private $adaptee; function __construct(Toy $adaptee) { $this->adaptee = $adaptee; } //委派調(diào)用Adaptee的sampleMethod1方法 public function doMouthOpen() { $this->adaptee->openMouth(); } public function doMouthClose() { $this->adaptee->closeMouth(); } } //類適配器角色:綠棗遙控公司 class GreenAdapter implements GreenTarget { private $adaptee; function __construct(Toy $adaptee) { $this->adaptee = $adaptee; } //委派調(diào)用Adaptee:GreenTarget的operateMouth方法 public function operateMouth($type = 0) { if ($type) { $this->adaptee->openMouth(); } else { $this->adaptee->closeMouth(); } } } class testDriver { public function run() { //實(shí)例化一只狗玩具 $adaptee_dog = new Dog(); echo "給狗套上紅棗適配器\n"; $adapter_red = new RedAdapter($adaptee_dog); //張嘴 $adapter_red->doMouthOpen(); //閉嘴 $adapter_red->doMouthClose(); echo "給狗套上綠棗適配器\n"; $adapter_green = new GreenAdapter($adaptee_dog); //張嘴 $adapter_green->operateMouth(1); //閉嘴 $adapter_green->operateMouth(0); } } $test = new testDriver(); $test->run();
php是一個(gè)嵌套的縮寫名稱,是英文超級(jí)文本預(yù)處理語言,它的語法混合了C、Java、Perl以及php自創(chuàng)新的語法,主要用來做網(wǎng)站開發(fā),許多小型網(wǎng)站都用php開發(fā),因?yàn)閜hp是開源的,從而使得php經(jīng)久不衰。
關(guān)于php中適配器模式的原理是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。