Php設計模式:行為型模式(三)
7、職責鏈模式 (Chainof Responsibility):
多個物件有機會處理請求,為請求發送者和接收者解耦。就像銀行裡的提款機,不管那一台都可以拿錢。
好處:簡化物件隱藏鏈結結構,方便新增職責節點。
弊端:請求可能沒有接受者,或被多個接收者調用,效能降低。
應用場景:處理多種請求。
程式碼實作:
<?php /** * 优才网公开课示例代码 * * 职责链模式 Chain of Responsibility * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } /** * 加入在公司里,如果你的请假时间小于0.5天,那么只需要向leader打声招呼就OK了。 如果0.5<=请假天数<=3天,需要先leader打声招呼,然后部门经理签字。 如果3<请假天数,需要先leader打声招呼,然后到部门经理签字,最后总经经理确认签字, 如果请假天数超过10天,是任何人都不能批准的。 */ /** * 抽象处理者角色(Handler:Approver):定义一个处理请求的接口,和一个后继连接(可选) * */ abstract class Handler { protected $_handler = null; protected $_handlerName = null; public function setSuccessor($handler) { $this->_handler = $handler; } protected function _success($request) { output(sprintf("%s's request was passed", $request->getName())); return true; } abstract function handleRequest($request); } /** * 具体处理者角色(ConcreteHandler:President):处理它所负责的请求,可以访问后继者,如果可以处理请求则处理,否则将该请求转给他的后继者。 * */ class ConcreteHandlerLeader extends Handler { function __construct($handlerName){ $this->_handlerName = $handlerName; } public function handleRequest($request) { if($request->getDay() < 0.5) { output(sprintf('%s was told', $this->_handlerName)); // 已经跟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; } public function handleRequest($request) { if(0.5 <= $request->getDay() && $request->getDay()<=3) { output(sprintf('%s signed', $this->_handlerName)); // 部门经理签字 return $this->_success($request); } if ($this->_handler instanceof Handler) { return $this->_handler->handleRequest($request); } } } class ConcreteHandlerGeneralManager extends Handler { function __construct($handlerName){ $this->_handlerName = $handlerName; } public function handleRequest($request) { if(3 < $request->getDay() && $request->getDay() < 10){ output(sprintf('%s signed', $this->_handlerName)); // 总经理签字 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')); } } } /** * 请假申请 * */ class Request { private $_name; private $_day; private $_reason; function __construct($name= '', $day= 0, $reason = ''){ $this->_name = $name; $this->_day = $day; $this->_reason = $reason; } public function setName($name){ $this->_name = $name; } public function getName(){ return $this->_name; } public function setDay($day){ $this->_day = $day; } public function getDay(){ return $this->_day ; } public function setReason($reason ){ $this->_reason = $reason; } public function getReason( ){ return $this->_reason; } } class Client { public static function test(){ $leader = new ConcreteHandlerLeader('leader'); $manager = new ConcreteHandlerManager('manager'); $generalManager = new ConcreteHandlerGeneralManager('generalManager'); //请求实例 $request = new Request('ucai',4,'休息'); $leader->setSuccessor($manager); $manager->setSuccessor($generalManager); $result = $leader->handleRequest($request); } } Client::test();
8、策略模式(Strategy):
定義一系列演算法,將每一個演算法封裝起來,並且使它們可互相取代。就像籃球隊裡的球員,場上的和場下休息的。教練可以讓場上的下來,也可以讓場下的上陣。
好處:定義可重複使用的一系列演算法和行為,並且消除了if else語句。
弊端:呼叫端必須知道所有策略類別。
應用場景:用於物件間的替換。
程式碼實作:
<?php /** * 优才网公开课示例代码 * * 策略模式 Strategy * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } //策略基类接口 interface IStrategy { public function OnTheWay(); } class WalkStrategy implements IStrategy { public function OnTheWay() { output( '在路上步行'); } } class RideBickStrategy implements IStrategy { public function OnTheWay() { output( '在路上骑自行车'); } } class CarStrategy implements IStrategy { public function OnTheWay() { output( '在路上开车'); } } //选择策略类Context class Context { public function find($strategy) { $strategy->OnTheWay(); } } class Client { public static function test(){ $travel = new Context(); $travel->find(new WalkStrategy()); $travel->find(new RideBickStrategy()); $travel->find(new CarStrategy()); } } Client::test();
已知模式
1、備忘錄模式(Memento):
保存物件在瞬間的狀態。親,還記得「老師來了記得叫我一下」的同桌的他嗎?
好處:提供使用者了一種可以恢復狀態的機制。
弊端:消耗資源。
應用場景:用於需要儲存的資料。
程式碼實作:
<?php /** * 优才网公开课示例代码 * * 备忘录模式 Memento * * @author 优才网全栈工程师教研组 * @see http://www.ucai.cn */ function output($string) { echo $string . "\n"; } class Originator { // 发起人(Originator)角色 private $_state; public function __construct() { $this->_state = ''; } public function createMemento() { // 创建备忘录 return new Memento($this->_state); } public function restoreMemento(Memento $memento) { // 将发起人恢复到备忘录对象记录的状态上 $this->_state = $memento->getState(); } public function setState($state) { $this->_state = $state; } public function getState() { return $this->_state; } public function showState() { output($this->_state); } } class Memento { // 备忘录(Memento)角色 private $_state; public function __construct($state) { $this->setState($state); } public function getState() { return $this->_state; } public function setState($state) { $this->_state = $state;} } class Caretaker { // 负责人(Caretaker)角色 private $_memento; public function getMemento() { return $this->_memento; } public function setMemento(Memento $memento) { $this->_memento = $memento; } } class Client { public static function test(){ $org = new Originator(); $org->setState('open'); $org->showState(); /* 创建备忘 */ $memento = $org->createMemento(); /* 通过Caretaker保存此备忘 */ $caretaker = new Caretaker(); $caretaker->setMemento($memento); /* 改变目标对象的状态 */ $org->setState('close'); $org->showState(); /* 还原操作 */ $org->restoreMemento($caretaker->getMemento()); $org->showState(); } } Client::test(); return; try { $db->beginTransaction(); $succ = $db->exec($sql_1); if (!$succ) { throw new Exception('SQL 1 update failed'); } $succ = $db->exec($sql_2); if (!$succ) { throw new Exception('SQL 2 update failed'); } $succ = $db->exec($sql_3); if (!$succ) { throw new Exception('SQL 3 update failed'); } $db->commit(); } catch (Exception $exp) { $db->rollBack(); }
深度模式
1、解釋器模式(Interpreter):
定義語言的文法,並建立一個解釋器來解釋該語言中的句子。每個用過字典的童鞋都懂滴。
好處:可擴充性較佳,且彈性高。
弊端:可能難以維持複雜的文法。
應用場景:用於成對或一對多的需求中。
2、訪客模式(Visitor):
封裝某些用於作用於某種資料結構中各元素的操作,可在不改變資料結構的前提下定義作用於這些元素的新操作。如銀行排號機。
好處:將相關的事物集中到一個訪客物件中。
弊端:增加新資料結構很困難。
應用場景:排隊,排號。
三、總結
本篇介紹了行為型模式,行為模式涉及到演算法和物件職責模式之間的分配,而行為類別模式採用繼承機制在類別間分派行為,TemplateMethod行為和preter 。行為物件模式使用物件複合而不是繼承,一些行為物件模式描述了一組相互對等的物件如何相互協作以完成其中任何一個物件都單獨無法完成的任務,如Mediator在物件之間引入一個mediator物件提供了松耦合所需的間接性;Chain of Responsibility提供了更鬆的耦合,它透過一條候選物件鏈隱式的向一個物件發松請求,可以運行時刻決定哪些候選者參與到鏈中;Observer定義並保持了物件間的依賴關係;其它的行為物件模式常將行為封裝在一個物件中,並將請求指派給它,Strategy模式將演算法封裝在物件中,這樣可以方面的改變和指定一個物件所使用的演算法;Command模式將請求封裝在物件中,這樣它就可以作為參數來傳遞,已可以儲存在歷史清單中或以其它方式使用;State模式封裝一個物件的狀態,使得當這個物件的狀態物件發生變化時,該物件可改變它的行為;Visitor模式封裝分佈於多個類別之間的行為;而Iterator模式則抽象化了存取和遍歷一個集合中物件的方式。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PHP 8.4 帶來了多項新功能、安全性改進和效能改進,同時棄用和刪除了大量功能。 本指南介紹如何在 Ubuntu、Debian 或其衍生版本上安裝 PHP 8.4 或升級到 PHP 8.4

Visual Studio Code,也稱為 VS Code,是一個免費的原始碼編輯器 - 或整合開發環境 (IDE) - 可用於所有主要作業系統。 VS Code 擁有大量針對多種程式語言的擴展,可以輕鬆編寫

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

本教程演示瞭如何使用PHP有效地處理XML文檔。 XML(可擴展的標記語言)是一種用於人類可讀性和機器解析的多功能文本標記語言。它通常用於數據存儲

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。
