<?php
//责任链模式定义:在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
//责任链模式涉及到的角色如下所示:
//抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。
//具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
/**
* 减免类
*/
class Reduce{
/**
* 减免金额
* @var float
*/
public $reduceMoney;
}
/**
* 审批抽象类(需要具体审批类实现)
*/
abstract class Manager{
/**
* 审批角色
* @var string
*/
protected $roleName;
/**
* 上级审批对象
* @var OBJECT
*/
protected $managerObj;
/**
* 设置审批角色名称
* @param string $roleName
*/
public function __construct($roleName) {
$this->roleName = $roleName;
}
/**
* 设置当前审批角色的上级角色
* @param Manager $manager
*/
public function setLeader(Manager $manager){
$this->managerObj = $manager;
}
//审批方法
abstract function audit(Reduce $reduce);
}
class LeaderManager extends Manager{
//可减免金额最大值
CONST REDUCE_MONEY = 1000;
/**
* 执行审批
* @param Reduce $reduce
*/
public function audit(Reduce $reduce) {
if($reduce->reduceMoney > self::REDUCE_MONEY){
//转发上级角色审批
$this->managerObj->audit($reduce);
}else{
echo $this->roleName."审批通过".PHP_EOL;
}
}
}
class ZongJianManager extends Manager{
//可减免金额最大值
CONST REDUCE_MONEY = 10000;
/**
* 执行审批
* @param Reduce $reduce
*/
public function audit(Reduce $reduce) {
if($reduce->reduceMoney > self::REDUCE_MONEY){
//转发上级角色审批
$this->managerObj->audit($reduce);
}else{
echo $this->roleName."审批通过".PHP_EOL;
}
}
}
class BossManager extends Manager{
//可减免金额最大值
CONST REDUCE_MONEY = 100000;
/**
* 执行审批
* @param Reduce $reduce
*/
public function audit(Reduce $reduce) {
if($reduce->reduceMoney > self::REDUCE_MONEY){
//转发上级角色审批
echo $this->roleName."审批拒绝".PHP_EOL;
}else{
echo $this->roleName."审批通过".PHP_EOL;
}
}
}
//客户端调用
$manage1 = new LeaderManager('组长');
$manage2 = new ZongJianManager('总监');
$manage3 = new BossManager('老板');
//实例化请求减免类
$reduce = new Reduce();
$reduce->reduceMoney = 1000000;
//设定层级关系
$manage1->setLeader($manage2);
$manage2->setLeader($manage3);
$manage1->audit($reduce);