1. 程式人生 > >B5:責任鏈模式 Chain Of Responsibility

B5:責任鏈模式 Chain Of Responsibility

con 出錯 耦合 idt uml fun .com function width

使多個對象都有機會處理處理請求,從而避免請求的發送者和接受者之間的耦合關系.將這個對象連成一條鏈,並沿著該鏈處理請求,直到有一個對象能夠處理它為止.

UML

技術分享

示例代碼:

abstract class Handle
{
    protected $nextHandle;

    public function setNextHandle(Handle $handle)
    {
        $this->nextHandle = $handle;
    }

    abstract public function handleRequest($level);
}

class Handle1 extends Handle
{
    public function handleRequest($level)
    {
        if ($level > 0 && $level < 10) {
            echo ‘Handle1 處理了‘;
        } elseif(!is_null($this->nextHandle)) {
            $this->nextHandle->handleRequest($level);
        }
    }
}

class Handle2 extends Handle
{
    public function handleRequest($level)
    {
        if ($level > 10 && $level < 100) {
            echo ‘Handle2 處理了‘;
        } elseif(!is_null($this->nextHandle)) {
            $this->nextHandle->handleRequest($level);
        }
    }
}

class Handle3 extends Handle
{
    public function handleRequest($level)
    {
        if ($level > 100 && $level < 1000) {
            echo ‘Handle3 處理了‘;
        } elseif(!is_null($this->nextHandle)) {
            $this->nextHandle->handleRequest($level);
        }
    }
}

$handle1 = new Handle1();
$handle2 = new Handle2();
$handle3 = new Handle3();
$handle1->setNextHandle($handle2);
$handle2->setNextHandle($handle3);

$handle1->handleRequest(600);

  

這個手動設置下一處理者,還是有點不方便.有時候設置出錯,容易導致死循環,我們改進一下.

示例代碼:

abstract class Handle
{
    abstract public function handleRequest($level);
}

class Handle1 extends Handle
{
    public function handleRequest($level)
    {
        if ($level > 0 && $level < 10) {
            echo ‘Handle1 處理了‘;
            return true;
        }
    }
}

class Handle2 extends Handle
{
    public function handleRequest($level)
    {
        if ($level > 10 && $level < 100) {
            echo ‘Handle2 處理了‘;
            return true;
        }
    }
}

class Handle3 extends Handle
{
    public function handleRequest($level)
    {
        if ($level > 100 && $level < 1000) {
            echo ‘Handle3 處理了‘;
            return true;
        }
    }
}

class Context
{
    protected $chains = [];

    public function addHandle(Handle $handle)
    {
        $this->chains[] = $handle;
    }

    public function handleRequest($level)
    {
        foreach ($this->chains as $handler) {
            if ($handler->handleRequest($level)) {
                break;
            }
        }
    }
}

$context = new Context();
$context->addHandle(new Handle1());
$context->addHandle(new Handle2());
$context->addHandle(new Handle3());

$context->handleRequest(600);

  

我們將鏈的設置交給Context,Context維護了一個數組來保存設置的處理者.context中的handleRequest方法,循環從數組中讀取並處理.在每個處理者類中,我們讓其如果有處理,就返回true,在foreach循環中跳出循環,防止無用的循環繼續下去.

當然有時候我們需要職責鏈的每個處理者挨個處理請求,也可以使用這種方法.

B5:責任鏈模式 Chain Of Responsibility