摘要:設(shè)計(jì)模式系列之入門設(shè)計(jì)模式是一套被反復(fù)使用多數(shù)人知曉的經(jīng)過(guò)分類編目的代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。毫無(wú)疑問(wèn),設(shè)計(jì)模式于己于他人于系統(tǒng)都是多贏的設(shè)計(jì)模式使代碼編制真正工程化設(shè)計(jì)模式是軟件工程的基石脈絡(luò),如同大廈的結(jié)構(gòu)一樣。
PHP設(shè)計(jì)模式系列之入門
前言設(shè)計(jì)模式(Design pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過(guò)分類編目的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。使用設(shè)計(jì)模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 毫無(wú)疑問(wèn),設(shè)計(jì)模式于己于他人于系統(tǒng)都是多贏的;設(shè)計(jì)模式使代碼編制真正工程化;設(shè)計(jì)模式是軟件工程的基石脈絡(luò),如同大廈的結(jié)構(gòu)一樣。
本系列文章不會(huì)直接上代碼直接進(jìn)行解釋,我一直認(rèn)為帶著問(wèn)題來(lái)學(xué)習(xí)是效率最高的學(xué)習(xí)方式。
本系列文章不會(huì)有演示截圖,你為什么不敲一遍加深印象呢,另外說(shuō)不定我的代碼有錯(cuò)。
我所寫的文章只是我對(duì)于編程的理解,如果有錯(cuò)誤希望能夠得到指正以免誤人子弟。
怎么樣才可以進(jìn)行設(shè)計(jì)模式的學(xué)習(xí)步子邁大了容易扯到蛋,如果在沒有熟悉 OOP 編程思想前就開始學(xué)習(xí)設(shè)計(jì)模式,我感覺會(huì)有兩種可能,不是“扯蛋”,就是“拉跨”。
當(dāng)然上面的話是一句玩笑話,學(xué)習(xí)設(shè)計(jì)模式可以有效的提高我們的代碼質(zhì)量與深入的理解 OOP 編程理念,如但是果在沒有扎實(shí)的功底(至少要要理解了抽象、接口、多態(tài))前就開始學(xué)習(xí)設(shè)計(jì)模式會(huì)越學(xué)越難,腦子越來(lái)越渾,那就真變成了從入門到放棄了,因?yàn)槟愕乃季S還沒有真正的走進(jìn) OOP(單身狗表示完全無(wú)法面向?qū)ο骬_^)。
對(duì)于設(shè)計(jì)模式的不理解我感覺主要分為兩種,一種是不知道怎么實(shí)現(xiàn)的,原因就是如上所述,另外一種是不知道為什么要這么用的,其實(shí)沒有必要糾結(jié)于為什么這么用,這么用了有啥作用,設(shè)計(jì)模式不過(guò)是與算法一樣只是為了實(shí)現(xiàn)某個(gè)特定環(huán)境下可以使用的一種更好的選擇。
更好一點(diǎn)的例子就是當(dāng)我們對(duì)一些數(shù)據(jù)進(jìn)行排序的時(shí)候,我們首先想到就是那幾個(gè)排序算法一樣,當(dāng)我們打著打著代碼突然靈光一閃,好像這個(gè)地方用這個(gè)設(shè)計(jì)模式寫起來(lái)會(huì)輕松一點(diǎn)。
當(dāng)碰到不懂得地方,思考一下,想不通,就出去走走,把這個(gè)東西放下來(lái),反正就算看到第二天凌晨也也是無(wú)用的,當(dāng)真正遇到問(wèn)題的時(shí)候,靈光一閃這個(gè)東西可以這么寫,然后去實(shí)踐,這就是我的學(xué)習(xí)之道。還有就是盡量去學(xué)實(shí)例,而不是去死扣概念,當(dāng)你真正用起來(lái)了,你也就差不多懂了,算法與數(shù)據(jù)結(jié)構(gòu)亦是如此。
本系列文章盡量以推導(dǎo)的形式來(lái)進(jìn)行書寫,而不是以現(xiàn)成的代碼來(lái)進(jìn)行講解,讓讀者知道設(shè)計(jì)模式是怎么來(lái)的也就是如何演化出來(lái)的,希望各位能夠喜歡。另外本系列的文章并不會(huì)提供運(yùn)行界面的截圖,如果想看看結(jié)果是否正確,為什么不自己試試呢?
設(shè)計(jì)模式嘗鮮(策略模式)開頭引用的話來(lái)自于百度百科,我相信很多剛剛開始接觸編程的人都會(huì)犯暈,因?yàn)樗腥硕疾幌矚g被學(xué)術(shù)化的文字,我們以設(shè)計(jì)模式中較為常用的策略模式來(lái)進(jìn)行演示,當(dāng)我們編寫一個(gè)廣告模塊的時(shí)候,公司給的要求是根據(jù)訪問(wèn)者的性別來(lái)進(jìn)行顯示廣告以提高轉(zhuǎn)化率,那我們應(yīng)該怎么寫呢?
首先我們想到的是在每一個(gè)廣告位上面都使用 if 判斷來(lái)判斷訪客的性別,這樣就能夠解決這樣的需求,那么我們的每一個(gè)廣告代碼的代碼塊可能是這個(gè)樣子的:
判斷 男 or 女{ 如果是男的就是男人的廣告 }else{ 顯示女人的廣告 }
既然偽代碼想好了,那么我們就可以著手進(jìn)行開發(fā)了,然后我們?cè)?if 代碼塊中添加各自的家在廣告代碼,于是就變成了下面的樣子:
if ($_GET["sex"] == "man") { echo "外星人大減價(jià)現(xiàn)在購(gòu)買立即送電競(jìng)?cè)鹞钠つw"; }else{ echo "卡西歐美顏相機(jī)不要錢免費(fèi)送!"; }
但是這是屬于一種硬編碼的編程方式,一旦我們?cè)黾恿四撤N需求,要求其年齡大于23歲顯示什么樣的廣告,那么我們就不得不在每一個(gè) if 判斷處再加上新的判斷條件,這樣的設(shè)計(jì)就是不合理的,為了提高可讀性與可維護(hù)性,我們會(huì)考慮建立兩個(gè)不同的類來(lái)對(duì)兩個(gè)廣告類來(lái)對(duì)其進(jìn)行管理。于是代碼變成了下面的樣子。
//index.php include "GenderAD.php"; include "ManAD.php"; if ($_GET["sex"] == "man") { $ad = new ManAD(); }else{ $ad = new GenderAD(); } $ad->show(); //GenderAD.php class GenderAD { public algorithm(){ echo "卡西歐美顏相機(jī)不要錢免費(fèi)送!"; } } //ManAD.php class ManAD{ public algorithm(){ echo "外星人大減價(jià)現(xiàn)在購(gòu)買立即送電競(jìng)?cè)鹞钠つw"; } }
algorithm 英[??lg?r?e?m] 美[??lɡ??r?e?m] n. 演算法; 運(yùn)算法則; 計(jì)算程序;
其實(shí)到了這一步就已經(jīng)算是一個(gè)簡(jiǎn)單的策略模式了,因?yàn)樗呀?jīng)具有策略的特質(zhì)了,只不過(guò)還不夠完善,如果說(shuō)這不算什么的話我也沒有辦法,因?yàn)樗械脑O(shè)計(jì)模式其實(shí)都是思維模式與表現(xiàn)形式罷了,就像上面的引用中提到的一樣,設(shè)計(jì)模式只不過(guò)是為了能夠讓代碼可以重用,更容易他讓人理解,因?yàn)槟愕拇a并不是你一個(gè)人在維護(hù),那么問(wèn)題來(lái)了,只是簡(jiǎn)單的對(duì)其進(jìn)行封裝真的就提高代碼的可維護(hù)性了么,其實(shí)并沒有,我們還沒有將 OOP 的設(shè)計(jì)概念發(fā)揮到極致。
經(jīng)過(guò)分析我們發(fā)現(xiàn)其實(shí) ManAD類和 GenderAD最終都要進(jìn)行顯示,他們的方法的顯示方法都是 show,如果是你一個(gè)人在開發(fā)那么沒有什么問(wèn)題,可是若是兩個(gè)人開發(fā)呢,你們可以直接可以對(duì)話的方式進(jìn)行溝通,協(xié)定好都是 show方法來(lái)顯示,可是為什么不用更工程化的方式來(lái)實(shí)現(xiàn)呢?
我們可以使用接口來(lái)實(shí)現(xiàn)這一目的,如果對(duì)接口還不了解,可以去查閱一下資料,很快你就能夠明白,在本文結(jié)束后我會(huì)在下方標(biāo)注出參考范例。
我們可以新建一個(gè)接口來(lái)對(duì)這些策略進(jìn)行控制。
interface ADinterface{ public function algorithm(); } class ManAD implements ADInterface { public function algorithm(){ echo "外星人大減價(jià)現(xiàn)在購(gòu)買立即送電競(jìng)?cè)鹞钠つw"; } } class GenderAD implements ADInterface { public function algorithm(){ echo "卡西歐美顏相機(jī)不要錢免費(fèi)送!"; } }
這樣一來(lái)廣告策略必須遵循這個(gè)接口進(jìn)行開發(fā),就保證了所有策略類都需要實(shí)現(xiàn) show 方法。
到目前為止,策略模式已經(jīng)相對(duì)的完善了,但是還是不夠完美,因?yàn)榇a依舊并不是很 OOP,我們其實(shí)還可以更進(jìn)一步,讓他更 OOP,我們可以對(duì)那些策略外面套一個(gè)殼子,給外面一個(gè)選擇器。
class StrategySelect { //具體策略對(duì)象 private $strategyInstance; //構(gòu)造函數(shù) public function __construct($instance) { $this->strategyInstance = $instance; } public function algorithm($strategy) { return $this->strategyInstance->algorithm(); } }
我們通過(guò)構(gòu)造函數(shù)接收到具體的執(zhí)行策略,然后使用algorithm()執(zhí)行相對(duì)應(yīng)的策略。
strategyInstance = $instance; } public function algorithm() { return $this->strategyInstance->algorithm(); } } class ManAD implements ADInterface { public function algorithm(){ echo "外星人大減價(jià)現(xiàn)在購(gòu)買立即送電競(jìng)?cè)鹞钠つw"; } } class GenderAD implements ADInterface { public function algorithm(){ echo "卡西歐相機(jī)免費(fèi)贈(zèng)送啦"; } } header("Content-type:text/html;charset=utf-8"); if ($_GET["sex"] == "man") { $stratey = new StrategySelect(new ManAD()); $stratey->algorithm(); }else{ $stratey = new StrategySelect(new GenderAD()); $stratey->algorithm(); }
Strategy其實(shí)算是一個(gè)策略選擇器,當(dāng)滿足一定條件的時(shí)候,我們通過(guò)這個(gè)策略選測(cè)器來(lái)進(jìn)行選擇相對(duì)應(yīng)的策略。這樣一來(lái)更符合邏輯。是不是很 OOP?
如果有什么不懂得可以在評(píng)論區(qū)進(jìn)行留言,有時(shí)間我會(huì)一一答復(fù),如果發(fā)現(xiàn)本文中有什么錯(cuò)誤請(qǐng)指出,我也害怕誤人子弟,特別是概念上的東西,在最后StrategySelect類的講解上我依舊感覺寫的很模糊,有些差強(qiáng)人意。
我的博客網(wǎng)址:www.aircrayon.xyz,有興趣的朋友可以去看看,不過(guò)上面的東西很久沒有更新了,而且有的博文內(nèi)容不全。
參考文檔《Leaning PHP Design Patterns》 William Sanders 著 蘇金國(guó) 王宇飛等譯
《PHP之道》
《PHP大話設(shè)計(jì)模式》 Rango(韓天峰) 錄制者 慕課網(wǎng)視頻教程
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/30469.html
平日學(xué)習(xí)接觸過(guò)的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二維碼 十大經(jīng)典排序算法(帶動(dòng)圖演示) 為什么知乎前端圈普遍認(rèn)為H5游戲和H5展示的JSer 個(gè)人整理和封裝的YU.js庫(kù)|中文詳細(xì)注釋|供新手學(xué)習(xí)使用 擴(kuò)展JavaScript語(yǔ)法記錄 - 掉坑初期工具 漢字拼音轉(zhuǎn)換...
平日學(xué)習(xí)接觸過(guò)的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二維碼 十大經(jīng)典排序算法(帶動(dòng)圖演示) 為什么知乎前端圈普遍認(rèn)為H5游戲和H5展示的JSer 個(gè)人整理和封裝的YU.js庫(kù)|中文詳細(xì)注釋|供新手學(xué)習(xí)使用 擴(kuò)展JavaScript語(yǔ)法記錄 - 掉坑初期工具 漢字拼音轉(zhuǎn)換...
平日學(xué)習(xí)接觸過(guò)的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二維碼 十大經(jīng)典排序算法(帶動(dòng)圖演示) 為什么知乎前端圈普遍認(rèn)為H5游戲和H5展示的JSer 個(gè)人整理和封裝的YU.js庫(kù)|中文詳細(xì)注釋|供新手學(xué)習(xí)使用 擴(kuò)展JavaScript語(yǔ)法記錄 - 掉坑初期工具 漢字拼音轉(zhuǎn)換...
平日學(xué)習(xí)接觸過(guò)的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個(gè)網(wǎng)址:http://www.kancloud.cn/jsfron... 1. Javascript 前端生成好看的二維碼 十大經(jīng)典排序算法(帶動(dòng)圖演示) 為什么知乎前端圈普遍認(rèn)為H5游戲和H5展示的JSer 個(gè)人整理和封裝的YU.js庫(kù)|中文詳細(xì)注釋|供新手學(xué)習(xí)使用 擴(kuò)展JavaScript語(yǔ)法記錄 - 掉坑初期工具 漢字拼音轉(zhuǎn)換...
摘要:更多資源請(qǐng)文章轉(zhuǎn)自月份前端資源分享視頻前端技術(shù)論壇融合不可錯(cuò)過(guò)的迷你庫(kù)測(cè)試框架實(shí)例教程為你詳細(xì)解讀請(qǐng)求頭的具體含意解析的庫(kù)如果要用前端框架,開發(fā)流程是怎樣的與有什么區(qū)別正確使用的方法是什么流程圖插件小如何讓元素只能輸入純文本前端技術(shù)中 更多資源請(qǐng)Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/jsfront...
閱讀 2922·2023-04-25 18:06
閱讀 2753·2021-11-22 09:34
閱讀 1767·2021-11-08 13:16
閱讀 1398·2021-09-24 09:47
閱讀 3101·2019-08-30 15:44
閱讀 2834·2019-08-29 17:24
閱讀 2657·2019-08-23 18:37
閱讀 2495·2019-08-23 16:55