- 什么是职责链模式?
- 什么情况用?
- 怎么用?
- 有啥优缺点?
你是谁?
职责链模式其实就是将请求者与服务者进行解耦,让多个可能接收请求的服务者组成一条链,请求沿着这条链一直传递,知道有服务者能够提供服务,处理请求为止。
啥时候用啊
老王是一个工作了5年的“程序猿”,这天老婆打电话,恭喜老王高升了,喜当爹了!老王那个激动啊,啥也别说了,还敲什么代码,赶紧回家啊! ???工作没干完,想回家生孩子?先请假! 咋请啊?老王有个小组长- -“半秃”,半秃上面还有个部门经理- -“谢顶”,谢顶上面还有个总经理- -“地中海”。
公司规定3天假,半秃批了就行,3-5天得谢顶批,5天以上地中海批。
没办法,生孩子怎么不得请个10天,但是还不能直接找地中海,得层层上报,好吧,老王只能先找半秃,半秃批完找谢顶,再找地中海。。。
这里就可以使用职责链模式,老王提了个 “请假” 的请求,服务者分别为 “半秃” --> “谢顶” --> “地中海”
具体咋用
职责链包含 三种角色:
Handler: 抽象处理者。定义了一个处理请求的方法。所有的处理者都必须实现该抽象类。
ConcreteHandler: 具体处理者。处理它所负责的请求,同时也可以访问它的后继者。如果它能够处理该请求则处理,否则将请求传递到它的后继者。
Client: 客户类。
老王请假实现:
<?php
include('init.php'); //笔者自己的,不需要引入
//申请类
class MyApplication
{
public $applicant;
public $leaveDay;
public function __construct($applicant, $leaveDay)
{
$this->applicant = $applicant;
$this->leaveDay = $leaveDay;
}
}
//服务者抽象类
abstract class Server
{
protected $serverName;
protected $nextServer;
public function __construct($serverName)
{
$this->serverName = $serverName;
}
public function setNextServer($nextServer)
{
$this->nextServer = $nextServer;
}
public abstract function dealApplication($myApplication);
}
//半秃服务者
class BanTu extends Server
{
public function dealApplication($myApplication)
{
if ($myApplication->leaveDay > 0 && $myApplication->leaveDay <= 3)
{
echo $this->serverName."同意了你的请求\n";
}
else if(null != $this->nextServer)
{
$this->nextServer->dealApplication($myApplication);
}
else
{
echo "不许请假!";
}
}
}
//谢顶服务者
class XieDing extends Server
{
public function dealApplication($myApplication)
{
if ($myApplication->leaveDay > 3 && $myApplication->leaveDay <= 5)
{
echo $this->serverName."同意了你的请求\n";
}
else if(null != $this->nextServer)
{
$this->nextServer->dealApplication($myApplication);
}
else
{
echo "不许请假!";
}
}
}
// 地中海服务者
class DizhongHai extends Server
{
public function dealApplication($myApplication)
{
if ($myApplication->leaveDay > 5)
{
echo $this->serverName."同意了你的请求\n";
}
else if(null != $this->nextServer)
{
$this->nextServer->dealApplication($myApplication);
}
else
{
echo "不许请假!";
}
}
}
class Client
{
public function laoWang()
{
$banTuServer = new BanTu("半秃");
$xieDingServer = new XieDing("谢顶");
$diZhongHaiServer = new DizhongHai("地中海");
$banTuServer->setNextServer($xieDingServer);
$xieDingServer->setNextServer($diZhongHaiServer);
$myApplication = new MyApplication("老王", 10);
$banTuServer->dealApplication($myApplication);
}
}
$run = new Client();
$run->laoWang();
?>
优缺点
优点
1、降低耦合度。将请求的发送者和接受者解耦。
2、简化了对象,请求对象不需要知道链的结构。
3、增强给对象指派职责的灵活性,通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
4、增加新的请求处理类很方便。
缺点
1、不能保证请求一定被接收。
2、系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。
3、可能不容易观察运行时的过程,debug不方便。