1. 程式人生 > >責任鏈模式實例:扣除用戶金幣/寫入金幣明細/發送消息

責任鏈模式實例:扣除用戶金幣/寫入金幣明細/發送消息

OS exce else protect 調用 handler 減少 用戶 write

功能:

扣除用戶金幣,寫入明細,並發送消息

以上三個動作任意一個動作失敗,則請求終止

一.定義一個異常類:

class HandleException extends Exception
{
}

  

二.定義一個虛擬類:

abstract class Handle
{
    protected $nextHandle;

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

    abstract public function handleRequest($request);
}

  

三.用戶金幣類:

class UserMoney extends Handle
{
    private $uid;
    private $money;

    public function __construct($uid, $money)
    {
        $this->uid      = $uid;
        $this->money    = $money;
    }

    public function handleRequest($request)
    {
        if ($this->money >= $request->money) {
            echo ‘扣除金幣成功<br>‘;
            $this->money -= $request->money;

            // 給請求附加新的金幣,便於金幣明細記錄
            $request->newMoney = $this->money;

            if ($this->nextHandle) {
                $this->nextHandle->handleRequest($request);
            }
        } else {
            throw new HandleException(‘金幣不足‘, 2001);
        }
    }
}

  

四.金幣明細類:

/**
 * 金幣明細
 * Class UserMoneyDetail
 */
class UserMoneyDetail extends Handle
{
    public function writeDb($request)
    {
        echo "寫入金幣明細成功,新的金幣數目為{$request->newMoney}<br>";
        return true;
    }

    public function handleRequest($request)
    {
        if ($this->writeDb($request)) {
            if ($this->nextHandle) {
                $this->nextHandle->handleRequest($request);
            }
        } else {
            throw new HandleException(‘金幣不足‘, 2002);
        }
    }
}

  

五.發送消息類:

class Message extends Handle
{
    public function sendMessage($request)
    {
        echo "UID為{$request->uid}的用戶減少了{$request->money}金幣,減少的後金幣為{$request->newMoney}";
        return true;
    }

    public function handleRequest($request)
    {
        if (! $this->sendMessage($request)) {
            throw new HandleException(‘發送郵件出錯‘, 2003);
        }
    }
}

  

六.調用

$request = (object) [‘uid‘ => 10, ‘money‘ => 500];

try {
    $userMoney          = new UserMoney($request->uid, 300);
    $userMoneyDetail    = new UserMoneyDetail();
    $message            = new Message();

    $userMoney->setNextHandle($userMoneyDetail);
    $userMoneyDetail->setNextHandle($message);

    $userMoney->handleRequest($request);
} catch (HandleException $e) {
    echo "發生錯誤:{$e->getMessage()}";
}

  

責任鏈模式實例:扣除用戶金幣/寫入金幣明細/發送消息