摘要:責(zé)任鏈模式權(quán)利越大的人管理越多,越嚴(yán)重的問題,越得往上級(jí)找,底層的人只能管理雞毛蒜皮的小事。使用適配器模式,轉(zhuǎn)成想通模式。
什么是設(shè)計(jì)模式
在軟件開發(fā)過程中,經(jīng)常出現(xiàn)的經(jīng)典場(chǎng)景的典型解決方案,稱為設(shè)計(jì)模式
如何學(xué)習(xí)設(shè)計(jì)模式
典型場(chǎng)景 --> 典型問題 --> 典型解決辦法
多態(tài)用來(lái)消除邏輯語(yǔ)句.
多態(tài)(ploymorphism)是一個(gè)生物學(xué)上的概念,指同一特種的多種表現(xiàn)形態(tài).
在面向?qū)ο笾?,指某種對(duì)象實(shí)例的不同表現(xiàn)形態(tài).
"; } } class MTiger extends Tiger { public function climb() { echo "Up" , "
"; } } class Cat { public function climb() { echo "Fly"; } } class Client { public static function call(Tiger $animal) { // 參數(shù)限定不嚴(yán)格,可以更加靈活, 可以傳遞一個(gè)父類類型,就可以有不同的子類形態(tài) $animal->climb(); } } Client::call(new XTiger()); Client::call(new MTiger()); Client::call(new Cat()); ?>
在23種設(shè)計(jì)模式中,可以有些模式可以自然消除的.
面向接口開發(fā)減少new 的操作.
熟悉概念:
調(diào)用端的概念
客戶端(Client)的概念
例如:在Java中,寫了一堆類,最終打成一個(gè)包。調(diào)用端可以把包引入,然后使用類中定義的方法,在開發(fā)過程中可以使用查看里面的方法。
假設(shè):開發(fā)中引入的是sdk,都不讓看。如何調(diào)用,必須開放一些接口。存在面向接口開發(fā)
接口:共同的規(guī)則
面向接口開發(fā)
"; } } class DbSqlite implements DB { public function conn() { echo "conn sqlite簡(jiǎn)單工廠模式
"; } } // ***客戶端**** (看不到DbMysql,DbSqlite的內(nèi)部實(shí)現(xiàn)細(xì)節(jié)) // 只知道,上述兩個(gè)類實(shí)現(xiàn)了db接口 $db = new DbMysql(); $db->conn(); $db = new DbSqlite(); $db->conn(); // 無(wú)論是開發(fā)者,還是調(diào)用者都是為接口負(fù)責(zé)
模式的作用:
發(fā)生連接的雙方,知道的越少越好.
在面向?qū)ο笤O(shè)計(jì)法則中,重要的開閉原則:對(duì)于修改是封閉的,對(duì)于擴(kuò)展是開放的.
"; } } class DbSqlite implements DB { public function conn() { echo "conn sqlite工廠方法
"; } } // 簡(jiǎn)單工廠 class Factory { public static function createDB($type) { if ($type == "mysql") { return new DbMysql(); } else if ($type == "sqlite") { return new DbSqlite(); } else { throw new Exception("Error db type", 1); } } } // 客戶端不知道服務(wù)端到底有哪些類名, // 只知道對(duì)方開放了一個(gè)Factory::createDB方法. // 靜態(tài)方法允許傳遞數(shù)據(jù)庫(kù)名稱 $msqyl = Factory::createDB("mysql"); $msqyl->conn(); $sqlit = Factory::createDB("sqlite"); $sqlit->conn(); // 如果增加oracle類型,怎么辦? // 服務(wù)端要修改Factory的內(nèi)容(在Java,C++中,改完之后還得再編譯) // 在面向?qū)ο笤O(shè)計(jì)法則中,重要的開閉原則 --- 對(duì)于修改是封閉的,對(duì)于擴(kuò)展是開放的. // 需求可以擴(kuò)展子類來(lái)實(shí)現(xiàn)。
進(jìn)行擴(kuò)展,避免對(duì)原有數(shù)據(jù)進(jìn)行修改,只需要新增代碼的子類,就可以完成。
對(duì)于修改是封閉的,對(duì)于擴(kuò)展是開放的.
"; } } class DbSqlite implements DB { public function conn() { echo "conn sqlite單例模式
"; } } class MySqlFactory implements Factory { public function createDB() { return new DbMysql(); } } class SqliteFactory implements Factory { public function createDB() { return new DbSqlite(); } } // ==== 服務(wù)器端添加oracle類 // 進(jìn)行擴(kuò)展,避免對(duì)原有數(shù)據(jù)進(jìn)行修改 class orcale implements DB { public function conn() { echo "conn orcal
"; } } class orcaleFactory implements Factory { public function createDB() { return new orcale(); } } // ------客戶端開始調(diào)用. $fact = new MysqlFactory(); $db = $fact->createDB(); $db->conn(); $fact = new SqliteFactory(); $db = $fact->createDB(); $db->conn();
常見使用場(chǎng)景:
需要數(shù)據(jù)庫(kù)類的時(shí)候
操作cookie類
上傳圖片類
DB.class.php Upload.class.php Cookie.class.php // 這三個(gè)類都需要讀取配置文件信息,而配置文件是共用的,因此配置讀取類有一個(gè)對(duì)象就夠了。 // (如何保證對(duì)象只有一個(gè))
PHP對(duì)象什么時(shí)候全等
二個(gè)對(duì)象是一個(gè)的時(shí)候.
單例模式實(shí)現(xiàn)
封閉外部new操作
內(nèi)部開公共接口,負(fù)責(zé)new操作,控制單一實(shí)例
禁止繼承覆蓋__construcotr
防止克隆
觀察者模式一個(gè)對(duì)象變化,引起其它對(duì)象的反應(yīng)??梢宰屍渌鼛讉€(gè)對(duì)象觀察變化的對(duì)象的反應(yīng).
一對(duì)多的關(guān)系.
優(yōu)點(diǎn):解耦。
觀察者模式中的三者: Subject, Observer, Client;
// Subject attach() // 記憶多個(gè)的對(duì)象 detach() // 告知記憶的對(duì)象,變化情況 notify() // 更新通知 // Observer update() // 更新對(duì)象中執(zhí)行的邏輯 // Client // 調(diào)用添加觀察者`attach()`JavaScript實(shí)現(xiàn)觀察者模式:
var select = document.querySelector("select"); var content = document.querySelector(".content"); var ad = document.querySelector(".ad"); // Subject select.observer = {}; // 添加觀察者 select.attach = function(key, obj) { this.observer[key] = obj; } // 刪除觀察者 select.detach = function(key) { delete this.observer[key]; } // 更新通知 select.onchange = select.ontify = function() { for (var key in this.observer) { this.observer[key].update(this); } } // Observer // 觀察者 content.update = function(observer) { // 參數(shù)是被觀察者對(duì)象 alert("content"); if (observer.value) { // 邏輯代碼 } } ad.update = function(observer) { // 參數(shù)是被觀察者對(duì)象 alert("ad"); if (observer.value) { // 邏輯代碼 } } // Client // 監(jiān)聽 select.attach("content", content); // 只需要把獨(dú)特的表示加入 對(duì)象key中 select.attach("ad", ad);PHP實(shí)現(xiàn)觀察者模式:
單一功能原則:類或者一個(gè)方法,完成一個(gè)功能即可.
PHP中內(nèi)置接口:
Splsubject
Splobserver
內(nèi)置類:
Splobjectstoragelognum = rand(1, 10); $this->hobby = $hobby; $this->observers = new SplObjectStorage(); } public function login() { // 類或者一個(gè)方法,完成一個(gè)功能即可. (單一功能原則) // 操作session $this->notify(); } public function attach(SplObserver $observer) { $this->observers->attach($observer); } public function detach(SplObserver $observer) { $this->observers->detach($observer); } public function notify() { $this->observers->rewind(); while($this->observers->valid()) { $observer = $this->observers->current(); $observer->update($this); $this->observers->next(); } } } /** 觀察者 */ class Secrity implements SplObserver { public function update(SplSubject $subject) { // 傳入的 對(duì)象是$subject,$subject是干什么,隨你的意. if($subject->lognum < 3) { echo "這個(gè)第" . $subject->lognum . "次安全登錄職責(zé)鏈模式
"; } else { echo "這個(gè)第" . $subject->lognum . "次登錄,異常
"; } } } class Ad implements SplObserver { public function update(SplSubject $subject) { if ($subject->hobby == "sport") { echo "sport,nba
"; } else { echo "good good study, day day up
"; } } } /** Client */ $user = new User("study"); $user->attach(new Secrity()); $user->attach(new Ad()); $user->login();也稱之為責(zé)任鏈模式(chain of resionbility)
對(duì)象產(chǎn)生的過程中,放在邏輯判斷中.
面向過程和面向?qū)ο蠡祀s在一塊,沒有充分拆開。責(zé)任鏈模式:
權(quán)利越大的人管理越多,越嚴(yán)重的問題,越得往上級(jí)找,底層的人只能管理雞毛蒜皮的小事。
每個(gè)人都有處理事情的,權(quán)利范圍.
責(zé)任鏈模式最終都需要都一級(jí)能夠處理.
先處理最近的一級(jí)
每個(gè)對(duì)象中有職責(zé)功能,上級(jí).
每個(gè)對(duì)象,儲(chǔ)存著對(duì)自己上級(jí)的引用,如果自己處理不了,交給上一級(jí)。優(yōu)點(diǎn):使用到那一級(jí)才會(huì)new 出那一級(jí)。
power) { echo "刪除"; } else { $top = new $this->top; $top->process($lev); } } } class admin { public $power = 2; protected $top = "police"; public function process($lev) { if ($lev <= $this->power) { echo "封閉"; } else { $top = new $this->top; $top->process($lev); } } } class police { protected $power; protected $top = null; public function process() { echo "抓!~"; } } $lev = 1; $judge = new borad(); // 距離最近的一級(jí) $judge->process($lev);策略模式和工廠模式相似的一種模式
calc = new $calc(); } public function calc($op1, $op2) { return $this->calc->calc($op1, $op2); } } $cmath = new CMath($op); var_dump($cmath->calc(10, 100));工廠方法和策略模式的區(qū)別:
裝飾器模式
工廠方法是傳遞不同參數(shù),直接把零件(子類)進(jìn)行操作。
策略模式是,真實(shí)的子類,虛擬成一個(gè)父類, 父類中操作(零件)子類。不需要直接碰子類,聚合成一個(gè)父類。問題:繼承層次越來(lái)越多、
content = $content; } public function decorator() { return $this->content; } } $art = new Article("goods goods study, day day up
"); echo $art->decorator(); // ----------------------------------------------------- // 文章需要, 需要編輯人員專門編輯 class BianArt extends article { // 重新加工對(duì)decorator public function summary() { return $this->content . "編輯摘要
"; } } $art = new BianArt("goods goods study, day day"); echo $art->summary(); // ----------------------------------------------------- // 文章需要, 需要做SEO class SeoArt extends BianArt { public function seo() { $content = $this->summary(); return $content . "seo
"; } } $art = new SeoArt("lz"); echo $art->seo(); // ----------------------------------------------------- // 文章需要,廣告部多帶帶管理 class Ad extends SeoArt { // 層次越來(lái)越深,目的是:給文章添加各種內(nèi)容 } // 繼承層次越來(lái)越多,裝飾器模式可以解決,變成倆級(jí)繼承使用裝飾器模式,修改多級(jí)繼承
父類負(fù)責(zé)主要邏輯,子類負(fù)責(zé)裝飾,修飾。(重寫父類的方法,裝飾之后再次返回)
content = $content; } public function decorator() { return $this->content; } } // 編輯文章 class BianArt extends BaseArt { public function __construct(BaseArt $art) { $this->art = $art; $this->decorator(); } public function decorator() { return $this->content = $this->art->decorator() . "編輯人員,文章摘要"; } } // SEO人員 class SeoArt extends BaseArt { public function __construct(BaseArt $art) { $this->art = $art; $this->decorator(); } public function decorator() { return $this->content = $this->art->decorator() . "SEO"; } } $art = new BaseArt("day day up"); // echo $art->decorator(); $art1 = new BianArt($art); // echo $art1->decorator(); $art2 = new SeoArt($art1); echo $art2->decorator();適配器模式把不適用的格式或者數(shù)據(jù)類型,轉(zhuǎn)換成適用目前場(chǎng)景
28, "wind" => 7, "sun" => 1); return serialize($today); } } // 增加一個(gè)代理,適配器 class AdapterTainqi extends tianqi { public static function show() { $today = parent::show(); $today = unserialize($today); $today = json_encode($today); return $today; } } // =====客戶端調(diào)用===== $taiqni = unserialize(tianqi::show()); echo "溫度:",$taiqni["tep"], "風(fēng)力:", $taiqni["wind"] , "橋接模式
"; // java客戶端,并不認(rèn)識(shí)PHP的串行化后的字符串。使用適配器模式,轉(zhuǎn)成想通模式。 $tq = AdapterTainqi::show(); $td = json_decode($tq); echo "溫度:",$td->tep, "風(fēng)力:", $td->wind;在某種場(chǎng)景下,多個(gè)條件有共同作用,增加耦合關(guān)系,減少邏輯復(fù)雜程度
這個(gè)世界上的因素都不是單一的,都是相互耦合的.send = $send; } abstract public function msg($content); public function send($to, $content) { $content = $this->msg($content); $this->send->send($to, $content); } } class zn { public function send($to, $content) { echo "zn: ", $to, "內(nèi)容是:", $content; } } class email { public function send($to, $content) { echo "email: ", $to, "內(nèi)容是:", $content; } } class sms { public function send($to, $content) { echo "sms: ", $to, "內(nèi)容是:", $content; } } class commonInfo extends info { public function msg($content) { return "common". $content; } } class warnInfo extends info { public function msg($content) { return "warn". $content; } } class dangerInfo extends info { public function msg($content) { return "danger". $content; } } // 站內(nèi)發(fā)普通信息 $commonInfo = new commonInfo(new zn()); $commonInfo->send("小明", "吃晚飯"); // sms發(fā)普通信息 $commonInfo = new commonInfo(new sms()); $commonInfo->send("小紅", "吃晚飯");
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/23034.html
摘要:一什么是單例設(shè)計(jì)模式單例模式,也叫單子模式,是一種常用的軟件設(shè)計(jì)模式。在應(yīng)用這個(gè)模式時(shí),單例對(duì)象的類必須保證只有一個(gè)實(shí)例存在。 一、什么是單例設(shè)計(jì)模式 單例模式,也叫單子模式,是一種常用的軟件設(shè)計(jì)模式。在應(yīng)用這個(gè)模式時(shí),單例對(duì)象的類必須保證只有一個(gè)實(shí)例存在。 二、單例模式的技巧 利用$_instance私有變量來(lái)保存類的唯一實(shí)例化對(duì)象; 設(shè)計(jì)一個(gè)getInstance對(duì)外公開的函數(shù),...
摘要:的設(shè)計(jì)模式有很多種,本文取最簡(jiǎn)單的三種模式工廠模式單例模式和注冊(cè)樹模式進(jìn)行簡(jiǎn)單的講解。文件創(chuàng)建完后,咱們回到單元測(cè)試文件文件再執(zhí)行一下單元測(cè)試命令發(fā)現(xiàn),也能返回成功,這樣的話我們就能很方便的修改任何驅(qū)動(dòng)了。 php 設(shè)計(jì)模式之工廠模式、單例模式、注冊(cè)樹模式 在軟件工程中,創(chuàng)建型設(shè)計(jì)模式承擔(dān)著對(duì)象創(chuàng)建的職責(zé),嘗試創(chuàng)建適合程序上下文的對(duì)象,對(duì)象創(chuàng)建設(shè)計(jì)模式的產(chǎn)生是由于軟件工程設(shè)計(jì)的問題,具...
摘要:?jiǎn)卫J筋櫭剂x,就是只有一個(gè)實(shí)例。為什么要使用單例模式語(yǔ)言本身的局限性語(yǔ)言是一種解釋型的腳本語(yǔ)言,這種運(yùn)行機(jī)制使得每個(gè)頁(yè)面被解釋執(zhí)行后,所有的相關(guān)資源都會(huì)被回收。 單例模式(Singleton Pattern):顧名思義,就是只有一個(gè)實(shí)例。作為對(duì)象的創(chuàng)建模式,單例模式確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例。 為什么要使用單例模式 1、PHP語(yǔ)言本身的局限性P...
摘要:類也是一個(gè)只包含構(gòu)造器的低級(jí)類,與和類相似。安裝擴(kuò)展對(duì)于平臺(tái),需要在中加入如下代碼上面的工作完成之后,還需要注意的是擴(kuò)展在配置文件中有獨(dú)立的代碼片段這些配置項(xiàng)主要是用來(lái)指定處理文件時(shí)使用緩存的行為。支持與擴(kuò)展類似的。 原文地址:PHP SOAP 擴(kuò)展,本文在原文基礎(chǔ)上添加了一些內(nèi)容和章節(jié),也加入了一些注釋,請(qǐng)讀者注意。 前兩篇文章 《SOAP 介紹》 和 《SOAP Web 服務(wù)介紹》...
摘要:特殊在,方法被對(duì)象調(diào)用執(zhí)行時(shí),會(huì)自動(dòng)確定是那個(gè)對(duì)象調(diào)用的該方法,會(huì)使用該對(duì)象為方法內(nèi)的賦值構(gòu)造析構(gòu)類,沒有作用域,作用域,只是講,函數(shù)內(nèi)和函數(shù)外。析構(gòu)在對(duì)象消失對(duì)象被銷毀時(shí),也會(huì)自動(dòng)執(zhí)行一個(gè)方法,稱之為析構(gòu)方法。 相關(guān)定義 對(duì)象(object):現(xiàn)實(shí)生活中的實(shí)體,在編程語(yǔ)言中的體現(xiàn)。實(shí)體都有屬性和功能。一組數(shù)據(jù),和操作管理這些數(shù)據(jù)的操作,定義在一起就形成了一個(gè)實(shí)體,稱之為對(duì)象。(屬性和...
摘要:服務(wù)器返回此響應(yīng)對(duì)或請(qǐng)求的響應(yīng)時(shí),會(huì)自動(dòng)將請(qǐng)求者轉(zhuǎn)到新位置。未授權(quán)請(qǐng)求要求身份驗(yàn)證。方法禁用禁用請(qǐng)求中指定的方法。請(qǐng)求范圍不符合要求如果頁(yè)面無(wú)法提供請(qǐng)求的范圍,則服務(wù)器會(huì)返回此狀態(tài)代碼。服務(wù)不可用服務(wù)器目前無(wú)法使用由于超載或停機(jī)維護(hù)。 PHP基礎(chǔ)篇 打印函數(shù) 簡(jiǎn)述一下echo print print_r var_dump區(qū)別 echo 輸出一個(gè)或多個(gè)字符串,無(wú)返回值print 僅支持一...
閱讀 3542·2021-10-09 09:41
閱讀 2745·2021-10-08 10:18
閱讀 2183·2021-09-10 10:51
閱讀 2680·2021-09-10 10:50
閱讀 776·2021-09-09 09:33
閱讀 3383·2021-09-06 15:14
閱讀 3017·2019-08-30 11:06
閱讀 3248·2019-08-29 14:04