版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhang_referee/article/details/82820750
职责链设计模式将请求的发送者与接受者分开,这样可以避免请求者与接收者的耦合。另外,这个模式允许将请求沿着一条链传递到不同的对象,使这些对象都有机会处理请求。
职责链的好处是:解耦性,缺点是当职责链比较长时,性能是一个问题。
想了半天,不怎么怎么举栗开始了,就以现实中学生在学校的行为及校方处理为例,开始下面的讲解。
我们不使用设计模式,代码可能如下:
<?php
class MonitorClass{
public function handler(){
echo "班长处理就行了";
}
}
class TeacherClass{
public function handler(){
echo "班主任处理";
}
}
class DepartmentLeader{
public function handler(){
echo "院系领导去处理";
}
}
class SchoolLeader{
public function handler(){
echo "校领导出面解决";
}
}
$actionArray = [
1 => 'Leave' , // 请假
2 => 'Escape class' , // 逃课
3 => 'cheating on a test', //考试作弊
4 => 'illegal' //违法
];
$handlerObj = null;
switch($actionArray[array_rand($actionArray,1)]){
case 'Leave':
$handlerObj = new MonitorClass();
break;
case 'Escape class':
$handlerObj = new TeacherClass();
break;
case 'cheating on a test':
$handlerObj = new DepartmentLeader();
break;
case 'illegal':
$handlerObj = new SchoolLeader();
break;
default :
break;
}
!empty($handlerObj) && $handlerObj->handler();
看起来,其实也没什么,很正常的代码,但如果你的业务经常发生变动,而你又不想总是改代码,那么使用设计模式是很有必要的,看下下面的一个初步的职责链模式实现方式。
<?php
class MonitorClass{
protected $can_handler_thing = 'Leave';
protected $superior = 'TeacherClass';
public function handler($can_handler_thing){
if($this->can_handler_thing == $can_handler_thing){
echo "班长可以处理";
}else{
$can_handler_obj = new $this->superior();
$can_handler_obj->handler($can_handler_thing);
}
}
}
class TeacherClass{
protected $can_handler_thing = 'Escape class';
protected $superior = 'DepartmentLeader';
public function handler($can_handler_thing){
if($this->can_handler_thing == $can_handler_thing){
echo "班主任处理";
}else{
$can_handler_obj = new $this->superior();
$can_handler_obj->handler($can_handler_thing);
}
}
}
class DepartmentLeader{
protected $can_handler_thing = 'cheating on a test';
protected $superior = 'SchoolLeader';
public function handler($can_handler_thing){
if($this->can_handler_thing == $can_handler_thing){
echo "院系领导去处理";
}else{
$can_handler_obj = new $this->superior();
$can_handler_obj->handler($can_handler_thing);
}
}
}
class SchoolLeader{
public function handler($can_handler_thing){
echo "校领导出面解决";
}
}
$actionArray = [
1 => 'Leave' , // 请假
2 => 'Escape class' , // 逃课
3 => 'cheating on a test', //考试作弊
4 => 'illegal' //违法
];
$handlerObj = new MonitorClass();
$handlerObj->handler($actionArray[array_rand($actionArray,1)]);
虽然使用职责链模式实现了,但耦合性还是很高,尤其是每个类里面的$superior ,这跟不使用职责链模式看起来没什么太大的区别嘛,改起来还是很麻烦的(改动还是有点多的),嗯嗯,那我们可以抽象出一个处理类出来,然后在进行具体的处理前,把三者连起来就可以,比如:
<?php
abstract class HandlerClass{
public $next_handler;
//设置下一个处理者
final public function setNexthandler($handler){
$this->next_handler = $handler;
}
abstract public function handler($handler); //自己要做的处理
}
class MonitorClass extends HandlerClass{
protected $can_handler_thing = 'Leave';
public function handler($handler){
if($this->can_handler_thing == $handler){
echo __ClASS__." can do";
}else{
$this->next_handler->handler($handler);
}
}
}
class TeacherClass extends HandlerClass{
protected $can_handler_thing = 'Escape class';
public function handler($handler){
if($this->can_handler_thing == $handler){
echo __ClASS__." can do";
}else{
$this->next_handler->handler($handler);
}
}
}
class DepartmentLeader extends HandlerClass{
protected $can_handler_thing = 'cheating on a test';
public function handler($handler){
if($this->can_handler_thing == $handler){
echo __ClASS__." can do";
}else{
$this->next_handler->handler($handler);
}
}
}
class SchoolLeader extends HandlerClass{
protected $can_handler_thing = 'cheating on a test';
public function handler($handler){
echo "只能由校方领导出马了";
}
}
$actionArray = [
1 => 'Leave' , // 请假
2 => 'Escape class' , // 逃课
3 => 'cheating on a test', //考试作弊
4 => 'illegal' //违法
];
$studentAction = $actionArray[array_rand($actionArray,1)];
$handlerObj = new MonitorClass();
$teacherObj = new TeacherClass();
$departmentObj = new DepartmentLeader();
$schoolObj = new SchoolLeader();
$handlerObj->setNexthandler($teacherObj);
$teacherObj->setNexthandler($departmentObj);
$departmentObj->setNexthandler($schoolObj);
$handlerObj->handler($studentAction);
这样,耦合性是很小,但每次处理,都要去把他们连在一起,当职责链条很长的时候,性能是个问题。个人觉得职责链模式是比较简单的,但在看书的时候被书中的一大堆不知所云的东西,搞得云里雾里的,可能举的栗子不太恰当,但只要说明问题就ok啦!