搜尋
首頁後端開發php教程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&#39;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(&#39;%s was told&#39;, $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(&#39;%s signed&#39;, $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(&#39;%s signed&#39;, $this->_handlerName));       // 总经理签字
            return $this->_success($request);  
        }  
        if ($this->_handler instanceof Handler) {  
            return $this->_handler->handleRequest($request);  
        } else {
            output(sprintf(&#39;no one can approve request more than 10 days&#39;));
        }
    }  
}  
/** 
 * 请假申请 
 * 
 */  
class Request  
{  
    private $_name;  
    private $_day;  
    private $_reason;  
  
    function __construct($name= &#39;&#39;, $day= 0, $reason = &#39;&#39;){  
        $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(&#39;leader&#39;);  
        $manager = new ConcreteHandlerManager(&#39;manager&#39;);  
        $generalManager = new ConcreteHandlerGeneralManager(&#39;generalManager&#39;);  
          
        //请求实例  
        $request = new Request(&#39;ucai&#39;,4,&#39;休息&#39;);  
          
        $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( &#39;在路上步行&#39;);
    }
}
class RideBickStrategy implements IStrategy {
    public function OnTheWay() {
        output( &#39;在路上骑自行车&#39;);
    }
}
class CarStrategy implements IStrategy {
    public function OnTheWay() {
        output( &#39;在路上开车&#39;);
    }
}
//选择策略类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 = &#39;&#39;;
    }
    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(&#39;open&#39;);
        $org->showState();
        /* 创建备忘 */
        $memento = $org->createMemento();
        /* 通过Caretaker保存此备忘 */
        $caretaker = new Caretaker();
        $caretaker->setMemento($memento);
        /* 改变目标对象的状态 */
        $org->setState(&#39;close&#39;);
        $org->showState();
        /* 还原操作 */
        $org->restoreMemento($caretaker->getMemento());
        $org->showState();
    }  
      
}  
  
Client::test(); 
return;
try {
    $db->beginTransaction();
    $succ   = $db->exec($sql_1);
    if (!$succ) {
        throw new Exception(&#39;SQL 1 update failed&#39;);
    }
    $succ   = $db->exec($sql_2);
    if (!$succ) {
        throw new Exception(&#39;SQL 2 update failed&#39;);
    }
    $succ   = $db->exec($sql_3);
    if (!$succ) {
        throw new Exception(&#39;SQL 3 update failed&#39;);
    }
    $db->commit();
} catch (Exception $exp) {
    $db->rollBack();
}

深度模式

1、解釋器模式(Interpreter):

         定義語言的文法,並建立一個解釋器來解釋該語言中的句子。每個用過字典的童鞋都懂滴。

         好處:可擴充性較佳,且彈性高。

         弊端:可能難以維持複雜的文法。

         應用場景:用於成對或一對多的需求中。

2、訪客模式(Visitor):

        封裝某些用於作用於某種資料結構中各元素的操作,可在不改變資料結構的前提下定義作用於這些元素的新操作。如銀行排號機。

        好處:將相關的事物集中到一個訪客物件中。

        弊端:增加新資料結構很困難。

        應用場景:排隊,排號。  

三、總結 

        本篇介紹了行為型模式,行為模式涉及到演算法和物件職責模式之間的分配,而行為類別模式採用繼承機制在類別間分派行為,TemplateMethod行為和preter 。行為物件模式使用物件複合而不是繼承,一些行為物件模式描述了一組相互對等的物件如何相互協作以完成其中任何一個物件都單獨無法完成的任務,如Mediator在物件之間引入一個mediator物件提供了松耦合所需的間接性;Chain of Responsibility提供了更鬆的耦合,它透過一條候選物件鏈隱式的向一個物件發松請求,可以運行時刻決定哪些候選者參與到鏈中;Observer定義並保持了物件間的依賴關係;其它的行為物件模式常將行為封裝在一個物件中,並將請求指派給它,Strategy模式將演算法封裝在物件中,這樣可以方面的改變和指定一個物件所使用的演算法;Command模式將請求封裝在物件中,這樣它就可以作為參數來傳遞,已可以儲存在歷史清單中或以其它方式使用;State模式封裝一個物件的狀態,使得當這個物件的狀態物件發生變化時,該物件可改變它的行為;Visitor模式封裝分佈於多個類別之間的行為;而Iterator模式則抽象化了存取和遍歷一個集合中物件的方式。


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
繼續使用PHP:耐力的原因繼續使用PHP:耐力的原因Apr 19, 2025 am 12:23 AM

PHP仍然流行的原因是其易用性、靈活性和強大的生態系統。 1)易用性和簡單語法使其成為初學者的首選。 2)與web開發緊密結合,處理HTTP請求和數據庫交互出色。 3)龐大的生態系統提供了豐富的工具和庫。 4)活躍的社區和開源性質使其適應新需求和技術趨勢。

PHP和Python:探索他們的相似性和差異PHP和Python:探索他們的相似性和差異Apr 19, 2025 am 12:21 AM

PHP和Python都是高層次的編程語言,廣泛應用於Web開發、數據處理和自動化任務。 1.PHP常用於構建動態網站和內容管理系統,而Python常用於構建Web框架和數據科學。 2.PHP使用echo輸出內容,Python使用print。 3.兩者都支持面向對象編程,但語法和關鍵字不同。 4.PHP支持弱類型轉換,Python則更嚴格。 5.PHP性能優化包括使用OPcache和異步編程,Python則使用cProfile和異步編程。

PHP和Python:解釋了不同的範例PHP和Python:解釋了不同的範例Apr 18, 2025 am 12:26 AM

PHP主要是過程式編程,但也支持面向對象編程(OOP);Python支持多種範式,包括OOP、函數式和過程式編程。 PHP適合web開發,Python適用於多種應用,如數據分析和機器學習。

PHP和Python:深入了解他們的歷史PHP和Python:深入了解他們的歷史Apr 18, 2025 am 12:25 AM

PHP起源於1994年,由RasmusLerdorf開發,最初用於跟踪網站訪問者,逐漸演變為服務器端腳本語言,廣泛應用於網頁開發。 Python由GuidovanRossum於1980年代末開發,1991年首次發布,強調代碼可讀性和簡潔性,適用於科學計算、數據分析等領域。

在PHP和Python之間進行選擇:指南在PHP和Python之間進行選擇:指南Apr 18, 2025 am 12:24 AM

PHP適合網頁開發和快速原型開發,Python適用於數據科學和機器學習。 1.PHP用於動態網頁開發,語法簡單,適合快速開發。 2.Python語法簡潔,適用於多領域,庫生態系統強大。

PHP和框架:現代化語言PHP和框架:現代化語言Apr 18, 2025 am 12:14 AM

PHP在現代化進程中仍然重要,因為它支持大量網站和應用,並通過框架適應開發需求。 1.PHP7提升了性能並引入了新功能。 2.現代框架如Laravel、Symfony和CodeIgniter簡化開發,提高代碼質量。 3.性能優化和最佳實踐進一步提升應用效率。

PHP的影響:網絡開發及以後PHP的影響:網絡開發及以後Apr 18, 2025 am 12:10 AM

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型?PHP類型提示如何起作用,包括標量類型,返回類型,聯合類型和無效類型?Apr 17, 2025 am 12:25 AM

PHP類型提示提升代碼質量和可讀性。 1)標量類型提示:自PHP7.0起,允許在函數參數中指定基本數據類型,如int、float等。 2)返回類型提示:確保函數返回值類型的一致性。 3)聯合類型提示:自PHP8.0起,允許在函數參數或返回值中指定多個類型。 4)可空類型提示:允許包含null值,處理可能返回空值的函數。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱工具

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境