[toc]
## 举个例子
> 如需请假, 根据天数的不同, 需要请示不同的领导
1. 小于等于2天,直属领导签字,提交行政部门;
2. 大于2天,小于等于5天,直属领导签字,部门总监签字,提交行政部门;
3. 大于5天,小于等于1月,直属领导签字,部门总监签字,CEO 签字,提交行政部门。
## 代码示例
```php
<?php
// 请求内容
class Request {
private $name;
private $dayoff;
private $reason;
private $leader;
public function __construct($name, $dayoff, $reason) {
$this->name = $name;
$this->dayoff = $dayoff;
$this->reason = $reason;
$this->leader = null;
}
public function getName() {
return $this->name;
}
public function getDayOff() {
return $this->dayoff;
}
public function getReason() {
return $this->reason;
}
}
// 责任人的抽象类
class Responsible {
private $name;
private $title;
private $nextHandler;
public function __init__($name, $title) {
$this->name = $name;
$this->title = $title;
$this->nextHandler = null;
}
public function getName() {
return $this->name;
}
public function getTitle() {
return $this->title;
}
public function setNextHandler($nextHandler) {
$this->nextHandler = $nextHandler;
}
public function getNextHandler() {
return $this->nextHandler;
}
public function handleRequest($request) {
}
}
// 请求者
class Person {
private $name;
private $leader;
public function __construct($name) {
$this->name = $name;
$this->leader = null;
}
public function setName($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
public function setLeader($leader) {
$this->leader = $leader;
}
public function getLeader() {
return $this->leader;
}
public function sendReuqest($request) {
echo $this->name . "申请请假" . $request->getDayOff() . "天。请假事由:" . $request->getReason();
if ($this->leader) {
$this->leader->handleRequest($request);
}
}
}
// 主管
class Supervisor extends Responsible {
public function __construct($name, $title) {
parent::__init__($name, $title);
}
public function handleRequest($request) {
if ($request->getDayOff() <= 2) {
echo "同意 " . $request->getName() . " 请假,签字人:" . $this->getName() . "(" . $this->getTitle() . ")" . PHP_EOL;
}
$nextHandler = $this->getNextHandler();
if ($nextHandler) {
$nextHandler->handleRequest($request);
}
}
}
// 部门总监
class DepartmentManager extends Responsible {
public function __construct($name, $title) {
parent::__init__($name, $title);
}
public function handleRequest($request) {
if ($request->getDayOff() > 2 and $request->getDayOff() <= 5) {
echo "同意 " . $request->getName() . " 请假,签字人:" . $this->getName() . "(" . $this->getTitle() . ")" . PHP_EOL;
}
$nextHandler = $this->getNextHandler();
if ($nextHandler) {
$nextHandler->handleRequest($request);
}
}
}
// CEO
class CEO extends Responsible {
public function __construct($name, $title) {
parent::__init__($name, $title);
}
public function handleRequest($request) {
if ($request->getDayOff() > 5 and $request->getDayOff() <= 22) {
echo "同意 " . $request->getName() . " 请假,签字人:" . $this->getName() . "(" . $this->getTitle() . ")" . PHP_EOL;
}
$nextHandler = $this->getNextHandler();
if ($nextHandler) {
$nextHandler->handleRequest($request);
}
}
}
// 行政人员
class Administrator extends Responsible {
public function __construct($name, $title) {
parent::__init__($name, $title);
}
public function handleRequest($request) {
echo $request->getName() . "的请假申请已审核,情况属实!已备案处理。处理人:" . $this->getName() . "(" . $this->getTitle() . ")\n";
$nextHandler = $this->getNextHandler();
}
}
// 测试
function test() {
$directLeader = new Supervisor("Eren", "客户端研发部经理");
$departmentLeader = new DepartmentManager("Eric", "技术研发中心总监");
$ceo = new CEO("Helen", "创新文化公司CEO");
$administrator = new Administrator("Nina", "行政中心总监");
$directLeader->setNextHandler($departmentLeader);
$departmentLeader->setNextHandler($ceo);
$ceo->setNextHandler($administrator);
$sunny = new Person("Sunny");
$sunny->setLeader($directLeader);
$sunny->sendReuqest(new Request($sunny->getName(), 1, "参加MDCC大会。"));
$tony = new Person("Tony");
$tony->setLeader($directLeader);
$tony->sendReuqest(new Request($tony->getName(), 5, "家里有紧急事情!"));
$pony = new Person("Pony");
$pony->setLeader($directLeader);
$pony->sendReuqest(new Request($pony->getName(), 15, "出国深造。"));
}
test();
```
```
D:\soft\php72\php.exe D:\project\php_dp\index.php
Sunny申请请假1天。请假事由:参加MDCC大会。同意 Sunny 请假,签字人:Eren(客户端研发部经理)
Sunny的请假申请已审核,情况属实!已备案处理。处理人:Nina(行政中心总监)
Tony申请请假5天。请假事由:家里有紧急事情!同意 Tony 请假,签字人:Eric(技术研发中心总监)
Tony的请假申请已审核,情况属实!已备案处理。处理人:Nina(行政中心总监)
Pony申请请假15天。请假事由:出国深造。同意 Pony 请假,签字人:Helen(创新文化公司CEO)
Pony的请假申请已审核,情况属实!已备案处理。处理人:Nina(行政中心总监)
Process finished with exit code 0
```
## 代码说明
> 你只需要填写`姓名`,`请假天数`, `请假理由`给行政即可, 至于应该让谁签字, 让管理层自己去判断, 如果权限不足, 就依次上报.
![](https://box.kancloud.cn/a46c3e2cf86bafdb94a8db8377b7ad17_734x160.png)
![](https://box.kancloud.cn/f8e588aa6e1d18bb84f8d7de3892a895_573x305.png)
## 什么是职责模式?
> 避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。职责模式也称为责任链模式,它是一种对象行为型模式。
> 职责链模式将请求的发送者和接受者解耦了。客户端不需要知道请求处理者的明确信息和处理的具体逻辑,甚至不需要知道链的结构,它只需要将请求进行发送即可。
## 设计要点
1. **请求者与请求内容**:谁要发送请求?发送请求的对象称为请求者。请求的内容通过发送请求时的参数进行传递。
1. **有哪些责任人**:责任人是构成责任链的关键要素。请求的流动方向是链条中的线,而责任人则是链条上的结点,线和结点才构成了一条链条。
1. **对责任人进行抽象**:真实世界中的责任人会多种多样,纷繁复杂,会有不同的职责和功能;但他们也有一个共同的特征——都可以处理请求。所以需要对责任人进行抽象,使他们具有责任的可传递性。
1. **责任人可自由组合**:责任链上的责任人可以根据业务的具体逻辑进行自由的组合和排序。
## 模式的优缺点
**优点**:
* 降低耦合度。它将请求的发送者和接受者解耦。
* 简化了对象。使得对象不需要知道链的结构。
* 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任人。
* 增加新的处理类很方便。
**职责模式的缺点**:
* 不能保证请求一定被接收。
* 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
## 应用场景
1. 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
1. 请求的处理具有明显的一层层传递关系。
1. 请求的处理流程和顺序需要程序运行时动态确定。