<接上一篇>
10年積累的網(wǎng)站設(shè)計(jì)制作、做網(wǎng)站經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有大關(guān)免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
5、中介者模式(Mediator):
用中介對(duì)象封裝一系列的對(duì)象交互,中介使各對(duì)象不需要顯式地相互引用。類似于郵局,郵寄者和收件者不用自己跑很遠(yuǎn)路,通過(guò)郵局就可以。
好處:簡(jiǎn)化了對(duì)象之間的關(guān)系,減少子類的生成
弊端:中介對(duì)象可能變得非常復(fù)雜,系統(tǒng)難以維護(hù)
應(yīng)用場(chǎng)景:不需要顯示地建立交互
代碼實(shí)現(xiàn):
_mediator = $mediator; } publicfunction send($message) { $this->_mediator->send($message,$this); } abstractpublic function notify($message); } class ConcreteMediator extends Mediator { // 具體中介者角色 private$_colleague1 = null; private$_colleague2 = null; publicfunction send($message,$colleague) { if($colleague == $this->_colleague1) { $this->_colleague1->notify($message); } else{ $this->_colleague2->notify($message); } } publicfunction set($colleague1,$colleague2) { $this->_colleague1 = $colleague1; $this->_colleague2 = $colleague2; } } class Colleague1 extends Colleague { // 具體對(duì)象角色 publicfunction notify($message) { output(sprintf('Colleague-1: %s', $message)); } } class Colleague2 extends Colleague { // 具體對(duì)象角色 publicfunction notify($message) { output(sprintf('Colleague-2: %s', $message)); } } class Client { publicstatic function test(){ //client $objMediator = new ConcreteMediator(); $objC1= new Colleague1($objMediator); $objC2= new Colleague2($objMediator); $objMediator->set($objC1,$objC2); $objC1->send("to c2 from c1"); $objC2->send("to c1 from c2"); } } Client::test();
6、狀態(tài)模式(State) :
對(duì)象在不同狀態(tài)下表現(xiàn)出不同的行為。就像女朋友一樣,高興了牽你的手,不高興了遛狗。在兩種狀態(tài)下變現(xiàn)出不同的行為。
好處:避免if語(yǔ)句實(shí)用,方便增加新?tīng)顟B(tài),封裝了狀態(tài)轉(zhuǎn)換規(guī)則。
弊端:增加系統(tǒng)類和對(duì)象的數(shù)量。
應(yīng)用場(chǎng)景:用于對(duì)象的不同功能的轉(zhuǎn)換。
代碼實(shí)現(xiàn):
state = $state; } //電梯門關(guān)閉 publicfunction close() { //電梯在什么狀態(tài)下才能關(guān)閉 switch($this->state) { case ILift::OPENING_STATE: //如果是則可以關(guān)門,同時(shí)修改電梯狀態(tài) $this->setState(ILift::CLOSING_STATE); break; case ILift::CLOSING_STATE: //如果電梯就是關(guān)門狀態(tài),則什么都不做 //do nothing; return ; break; case ILift::RUNNING_STATE: //如果是正在運(yùn)行,門本來(lái)就是關(guān)閉的,也說(shuō)明都不做 //do nothing; return ; break; case ILift::STOPPING_STATE: //如果是停止?fàn)顟B(tài),本也是關(guān)閉的,什么也不做 //do nothing; return ; break; } output('Lift colse'); } //電梯門開(kāi)啟 publicfunction open() { //電梯在什么狀態(tài)才能開(kāi)啟 switch($this->state){ case ILift::OPENING_STATE: //如果已經(jīng)在門敞狀態(tài),則什么都不做 //do nothing; return ; break; case ILift::CLOSING_STATE: //如是電梯時(shí)關(guān)閉狀態(tài),則可以開(kāi)啟 $this->setState(ILift::OPENING_STATE); break; case ILift::RUNNING_STATE: //正在運(yùn)行狀態(tài),則不能開(kāi)門,什么都不做 //do nothing; return ; break; case ILift::STOPPING_STATE: //停止?fàn)顟B(tài),淡然要開(kāi)門了 $this->setState(ILift::OPENING_STATE); break; } output('Lift open'); } ///電梯開(kāi)始跑起來(lái) publicfunction run() { switch($this->state){ case ILift::OPENING_STATE: //如果已經(jīng)在門敞狀態(tài),則不你能運(yùn)行,什么都不做 //do nothing; return ; break; case ILift::CLOSING_STATE: //如是電梯時(shí)關(guān)閉狀態(tài),則可以運(yùn)行 $this->setState(ILift::RUNNING_STATE); break; case ILift::RUNNING_STATE: //正在運(yùn)行狀態(tài),則什么都不做 //do nothing; return ; break; case ILift::STOPPING_STATE: //停止?fàn)顟B(tài),可以運(yùn)行 $this->setState(ILift::RUNNING_STATE); } output('Lift run'); } //電梯停止 publicfunction stop() { switch($this->state){ case ILift::OPENING_STATE: //如果已經(jīng)在門敞狀態(tài),那肯定要先停下來(lái)的,什么都不做 //do nothing; return ; break; case ILift::CLOSING_STATE: //如是電梯時(shí)關(guān)閉狀態(tài),則當(dāng)然可以停止了 $this->setState(ILift::CLOSING_STATE); break; case ILift::RUNNING_STATE: //正在運(yùn)行狀態(tài),有運(yùn)行當(dāng)然那也就有停止了 $this->setState(ILift::CLOSING_STATE); break; case ILift::STOPPING_STATE: //停止?fàn)顟B(tài),什么都不做 //do nothing; return ; break; } output('Lift stop'); } } class Client { publicstatic function test() { $lift= new Lift(); //電梯的初始條件應(yīng)該是停止?fàn)顟B(tài) $lift->setState(ILift::STOPPING_STATE); //首先是電梯門開(kāi)啟,人進(jìn)去 $lift->open(); //然后電梯門關(guān)閉 $lift->close(); //再然后,電梯跑起來(lái),向上或者向下 $lift->run(); //最后到達(dá)目的地,電梯挺下來(lái) $lift->stop(); } } Client::test();
_context = $context; } //首先電梯門開(kāi)啟動(dòng)作 publicabstract function open(); //電梯門有開(kāi)啟,那當(dāng)然也就有關(guān)閉了 publicabstract function close(); //電梯要能上能下,跑起來(lái) publicabstract function run(); //電梯還要能停下來(lái),停不下來(lái)那就扯淡了 publicabstract function stop(); } /** * 環(huán)境類:定義客戶感興趣的接口。維護(hù)一個(gè)ConcreteState子類的實(shí)例,這個(gè)實(shí)例定義當(dāng)前狀態(tài)。 */ class Context { //定義出所有的電梯狀態(tài) static $openningState =null; static $closeingState =null; static $runningState = null; static $stoppingState =null; publicfunction __construct() { self::$openningState = new OpenningState(); self::$closeingState = new ClosingState(); self::$runningState = new RunningState(); self::$stoppingState = new StoppingState(); } //定一個(gè)當(dāng)前電梯狀態(tài) private $_liftState; publicfunction getLiftState() { return$this->_liftState; } publicfunction setLiftState($liftState) { $this->_liftState = $liftState; //把當(dāng)前的環(huán)境通知到各個(gè)實(shí)現(xiàn)類中 $this->_liftState->setContext($this); } publicfunction open(){ $this->_liftState->open(); } publicfunction close(){ $this->_liftState->close(); } publicfunction run(){ $this->_liftState->run(); } publicfunction stop(){ $this->_liftState->stop(); } } /** * 在電梯門開(kāi)啟的狀態(tài)下能做什么事情 */ class OpenningState extends LiftState { /** * 開(kāi)啟當(dāng)然可以關(guān)閉了,我就想測(cè)試一下電梯門開(kāi)關(guān)功能 * */ publicfunction close() { //狀態(tài)修改 $this->_context->setLiftState(Context::$closeingState); //動(dòng)作委托為CloseState來(lái)執(zhí)行 $this->_context->getLiftState()->close(); } //打開(kāi)電梯門 publicfunction open() { output('lift open...'); } //門開(kāi)著電梯就想跑,這電梯,嚇?biāo)滥悖?nbsp; publicfunction run() { //donothing; } //開(kāi)門還不停止? publicfunction stop() { //donothing; } } /** * 電梯門關(guān)閉以后,電梯可以做哪些事情 */ class ClosingState extends LiftState { //電梯門關(guān)閉,這是關(guān)閉狀態(tài)要實(shí)現(xiàn)的動(dòng)作 publicfunction close() { output('lift close...'); } //電梯門關(guān)了再打開(kāi),逗你玩呢,那這個(gè)允許呀 publicfunction open() { $this->_context->setLiftState(Context::$openningState); //置為門敞狀態(tài) $this->_context->getLiftState()->open(); } //電梯門關(guān)了就跑,這是再正常不過(guò)了 publicfunction run() { $this->_context->setLiftState(Context::$runningState); //設(shè)置為運(yùn)行狀態(tài); $this->_context->getLiftState()->run(); } //電梯門關(guān)著,我就不按樓層 publicfunction stop() { $this->_context->setLiftState(Context::$stoppingState); //設(shè)置為停止?fàn)顟B(tài); $this->_context->getLiftState()->stop(); } } /** * 電梯在運(yùn)行狀態(tài)下能做哪些動(dòng)作 */ class RunningState extends LiftState { //電梯門關(guān)閉?這是肯定了 publicfunction close() { //donothing } //運(yùn)行的時(shí)候開(kāi)電梯門?你瘋了!電梯不會(huì)給你開(kāi)的 publicfunction open() { //donothing } //這是在運(yùn)行狀態(tài)下要實(shí)現(xiàn)的方法 publicfunction run() { output('lift run...'); } //這個(gè)事絕對(duì)是合理的,光運(yùn)行不停止還有誰(shuí)敢做這個(gè)電梯?!估計(jì)只有上帝了 publicfunction stop() { $this->_context->setLiftState(Context::$stoppingState); //環(huán)境設(shè)置為停止?fàn)顟B(tài); $this->_context->getLiftState()->stop(); } } /** * 在停止?fàn)顟B(tài)下能做什么事情 */ class StoppingState extends LiftState { //停止?fàn)顟B(tài)關(guān)門?電梯門本來(lái)就是關(guān)著的! publicfunction close() { //donothing; } //停止?fàn)顟B(tài),開(kāi)門,那是要的! publicfunction open() { $this->_context->setLiftState(Context::$openningState); $this->_context->getLiftState()->open(); } //停止?fàn)顟B(tài)再跑起來(lái),正常的很 publicfunction run() { $this->_context->setLiftState(Context::$runningState); $this->_context->getLiftState()->run(); } //停止?fàn)顟B(tài)是怎么發(fā)生的呢?當(dāng)然是停止方法執(zhí)行了 publicfunction stop() { output('lift stop...'); } } /** * 模擬電梯的動(dòng)作 */ class Client { publicstatic function test() { $context = new Context(); $context->setLiftState(new ClosingState()); $context->open(); $context->close(); $context->run(); $context->stop(); } } Client::test();
7、職責(zé)鏈模式 (Chainof Responsibility):
多個(gè)對(duì)象有機(jī)會(huì)處理請(qǐng)求,為請(qǐng)求發(fā)送者和接收者解耦。就像銀行里的取款機(jī),不管那一臺(tái)都可以取到錢。
好處:簡(jiǎn)單化對(duì)象隱藏鏈結(jié)構(gòu),便于添加新職責(zé)節(jié)點(diǎn)
弊端:請(qǐng)求可能沒(méi)有接受者,或者被多個(gè)接收者調(diào)用,性能降低
應(yīng)用場(chǎng)景:處理多種請(qǐng)求
代碼實(shí)現(xiàn):
_handler = $handler; } protected function_success($request) { output(sprintf("%s's request was passed",$request->getName())); returntrue; } abstractfunction handleRequest($request); } /** * 具體處理者角色(ConcreteHandler:President):處理它所負(fù)責(zé)的請(qǐng)求,可以訪問(wèn)后繼者,如果可以處理請(qǐng)求則處理,否則將該請(qǐng)求轉(zhuǎn)給他的后繼者。 * */ class ConcreteHandlerLeader extends Handler { function__construct($handlerName){ $this->_handlerName = $handlerName; } publicfunction handleRequest($request) { if($request->getDay() < 0.5) { output(sprintf('%s was told', $this->_handlerName)); // 已經(jīng)跟leader招呼了 return $this->_success($request); } if($this->_handler instanceof Handler) { return $this->_handler->handleRequest($request); } } } /** * Manager * */ class ConcreteHandlerManager extends Handler { function__construct($handlerName){ $this->_handlerName = $handlerName; } publicfunction handleRequest($request) { if(0.5<= $request->getDay() && $request->getDay()<=3) { output(sprintf('%s signed',$this->_handlerName)); // 部門經(jīng)理簽字 return $this->_success($request); } if($this->_handler instanceof Handler) { return $this->_handler->handleRequest($request); } } } class ConcreteHandlerGeneralManager extendsHandler { function__construct($handlerName){ $this->_handlerName = $handlerName; } publicfunction handleRequest($request) { if(3< $request->getDay() && $request->getDay() < 10){ output(sprintf('%s signed', $this->_handlerName)); // 總經(jīng)理簽字 return $this->_success($request); } if($this->_handler instanceof Handler) { return $this->_handler->handleRequest($request); } else{ output(sprintf('no one can approve request more than 10 days')); } } } /** * 請(qǐng)假申請(qǐng) * */ class Request { private$_name; private$_day; private$_reason; function__construct($name= '', $day= 0, $reason = ''){ $this->_name = $name; $this->_day = $day; $this->_reason = $reason; } publicfunction setName($name){ $this->_name = $name; } publicfunction getName(){ return $this->_name; } publicfunction setDay($day){ $this->_day = $day; } publicfunction getDay(){ return $this->_day ; } publicfunction setReason($reason ){ $this->_reason = $reason; } publicfunction getReason( ){ return $this->_reason; } } class Client { publicstatic function test(){ $leader= new ConcreteHandlerLeader('leader'); $manager = new ConcreteHandlerManager('manager'); $generalManager = newConcreteHandlerGeneralManager('generalManager'); //請(qǐng)求實(shí)例 $request = new Request('ucai',4,'休息'); $leader->setSuccessor($manager); $manager->setSuccessor($generalManager); $result = $leader->handleRequest($request); } } Client::test();
8、策略模式(Strategy):
定義一系列算法,把每一個(gè)算法封裝起來(lái),并且使它們可相互替換。就像籃球隊(duì)里的球員,場(chǎng)上的和場(chǎng)下休息的。教練可以讓場(chǎng)上的下來(lái),也可以讓場(chǎng)下的上陣。
好處:定義可重用的一系列算法和行為,并且消除了if else語(yǔ)句
弊端:調(diào)用端必須知道所有策略類
應(yīng)用場(chǎng)景:用于對(duì)象間的替換
代碼實(shí)現(xiàn):
OnTheWay(); } } class Client { publicstatic function test(){ $travel = new Context(); $travel->find(new WalkStrategy()); $travel->find(new RideBickStrategy()); $travel->find(new CarStrategy()); } } Client::test();
已知模式
1、備忘錄模式(Memento):
保存對(duì)象在一時(shí)刻的狀態(tài)。親,還記得“老師來(lái)了記得叫我一下”的同桌的他嗎?
好處:給用戶提供了一種可以恢復(fù)狀態(tài)的機(jī)制
弊端:消耗資源
應(yīng)用場(chǎng)景:用于需要保存的數(shù)據(jù)
代碼實(shí)現(xiàn):
_state = ''; } publicfunction createMemento() { // 創(chuàng)建備忘錄 returnnew Memento($this->_state); } publicfunction restoreMemento(Memento $memento) { // 將發(fā)起人恢復(fù)到備忘錄對(duì)象記錄的狀態(tài)上 $this->_state = $memento->getState(); } publicfunction setState($state) { $this->_state = $state; } publicfunction getState() { return $this->_state; } publicfunction showState() { output($this->_state); } } class Memento { // 備忘錄(Memento)角色 private$_state; publicfunction __construct($state) { $this->setState($state); } publicfunction getState() { return $this->_state; } publicfunction setState($state) { $this->_state = $state;} } class Caretaker { // 負(fù)責(zé)人(Caretaker)角色 private$_memento; public functiongetMemento() { return $this->_memento; } publicfunction setMemento(Memento $memento) { $this->_memento = $memento; } } class Client { publicstatic function test(){ $org =new Originator(); $org->setState('open'); $org->showState(); /* 創(chuàng)建備忘 */ $memento = $org->createMemento(); /* 通過(guò)Caretaker保存此備忘 */ $caretaker = new Caretaker(); $caretaker->setMemento($memento); /* 改變目標(biāo)對(duì)象的狀態(tài) */ $org->setState('close'); $org->showState(); /* 還原操作 */ $org->restoreMemento($caretaker->getMemento()); $org->showState(); } } Client::test(); return; try { $db->beginTransaction(); $succ = $db->exec($sql_1); if(!$succ) { thrownew Exception('SQL 1 update failed'); } $succ = $db->exec($sql_2); if(!$succ) { thrownew Exception('SQL 2 update failed'); } $succ = $db->exec($sql_3); if(!$succ) { throw newException('SQL 3 update failed'); } $db->commit(); } catch (Exception $exp) { $db->rollBack(); }
深度模式
1、解釋器模式(Interpreter):
定義語(yǔ)言的文法,并建立一個(gè)解釋器解釋該語(yǔ)言中的句子。每個(gè)用過(guò)字典的童鞋都懂滴。
好處:可擴(kuò)展性比較好,靈活性大
弊端:可能難以維護(hù)復(fù)雜的文法
應(yīng)用場(chǎng)景:用于成對(duì)或者一對(duì)多的需求中
2、訪問(wèn)者模式(Visitor):
封裝某些用于作用于某種數(shù)據(jù)結(jié)構(gòu)中各元素的操作,可以在不改變數(shù)據(jù)結(jié)構(gòu)的前提下定義作用于這些元素的新操作。如銀行排號(hào)機(jī)。
好處:將相關(guān)的事物集中到一個(gè)訪問(wèn)者對(duì)象中。
弊端:增加新數(shù)據(jù)結(jié)構(gòu)很困難
應(yīng)用場(chǎng)景:排隊(duì),排號(hào)
三、總結(jié)
本篇介紹了行為型模式,行為模式涉及到算法和對(duì)象職責(zé)間的分配,行為類模式采用繼承機(jī)制在類間分派行為,TemplateMethod和Interpreter是類行為模式。行為對(duì)象模式使用對(duì)象復(fù)合而不是繼承,一些行為對(duì)象模式描述了一組相互對(duì)等的對(duì)象如何相互協(xié)作以完成其中任何一個(gè)對(duì)象都單獨(dú)無(wú)法完成的任務(wù),如Mediator在對(duì)象間引入一個(gè)mediator對(duì)象提供了松耦合所需的間接性;Chain of Responsibility提供了更松的耦合,它通過(guò)一條候選對(duì)象鏈隱式的向一個(gè)對(duì)象發(fā)松請(qǐng)求,可以運(yùn)行時(shí)刻決定哪些候選者參與到鏈中;Observer定義并保持了對(duì)象間的依賴關(guān)系;其它的行為對(duì)象模式常將行為封裝封裝在一個(gè)對(duì)象中,并將請(qǐng)求指派給它,Strategy模式將算法封裝在對(duì)象中,這樣可以方面的改變和指定一個(gè)對(duì)象所使用的算法;Command模式將請(qǐng)求封裝在對(duì)象中,這樣它就可以作為參數(shù)來(lái)傳遞,已可以存儲(chǔ)在歷史列表中或以其它方式使用;State模式封裝一個(gè)對(duì)象的狀態(tài),使得當(dāng)這個(gè)對(duì)象的狀態(tài)對(duì)象變化時(shí),該對(duì)象可改變它的行為;Visitor模式封裝分布于多個(gè)類之間的行為;而Iterator模式則抽象了訪問(wèn)和遍歷一個(gè)集合中對(duì)象的方式。