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