功能:
扣除用户金币,写入明细,并发送消息
以上三个动作任意一个动作失败,则请求终止
一.定义一个异常类:
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()}";
}
我们手动设置了每个责任类的下一链,我们还可以建立一个上下文类,来统一管理一系列的动作;关键性更改如下:
取消设置下一链
abstract class 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;
} else {
throw new HandleException('金币不足', 2001);
}
}
}
创建一个context类
class Context
{
protected $chains = [];
public function addChain(Handle $handle)
{
$this->chains[] = $handle;
}
public function handle($request) {
foreach ($this->chains as $handle) {
$handle->handleRequest($request);
}
}
}
调用:
$request = (object) ['uid' => 10, 'money' => 300];
try {
$context = new Context();
$userMoney = new UserMoney($request->uid, 1000);
$userMoneyDetail = new UserMoneyDetail();
$message = new Message();
$context->addChain($userMoney);
$context->addChain($userMoneyDetail);
$context->addChain($message);
$context->handle($request);
} catch (HandleException $e) {
echo "发生错误:{$e->getMessage()}";