微信扫一扫打赏支持

php设计模式之责任链模式

php设计模式之责任链模式

实际问题

你的论坛有举报功能,版主能解决粗口方面的举报,警察能解决严重一点的黄赌毒方面的举报,更严重的反政府的举报就需要由国安局来完成。

职场中每个人都有直属的上级,如果到达自己的问题自己能够处理,就自己处理,否则交给上级。这里相当于警察是版主的上级,国安是警察的上级。

 

简介

职责链模式(又叫责任链模式)包含了一些命令对象和一些处理对象,每个处理对象决定它能处理那些命令对象,它也知道应该把自己不能处理的命令对象交下一个处理对象,该模式还描述了往该链添加新的处理对象的方法。 

职场中每个人都有直属的上级,如果到达自己的问题自己能够处理,就自己处理,否则交给上级。

当一个问题来到的时候,将这个问题交给最低级的处理者,能处理就处理,不能处理就往上面传。

每个管理者都有指向上级的一个指针。

 

类图

 

 

 

角色:          

       抽象处理者(Manager):定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或接口实现。

       具体处理者(CommonManager):具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

 

代码

  1 <?php
  2 /**
  3  * Created by PhpStorm.
  4  * User: Jang
  5  * Date: 2015/6/11
  6  * Time: 10:16
  7  */
  8 
  9 //申请Model
 10 class Request
 11 {
 12     //数量
 13     public $num;
 14     //申请类型
 15     public $requestType;
 16     //申请内容
 17     public $requestContent;
 18 }
 19 
 20 //抽象管理者
 21 abstract class Manager
 22 {
 23     protected $name;
 24     //管理者上级
 25     protected $manager;
 26     public function __construct($_name)
 27     {
 28         $this->name = $_name;
 29     }
 30 
 31     //设置管理者上级
 32     public function SetHeader(Manager $_mana)
 33     {
 34         $this->manager = $_mana;
 35     }
 36 
 37     //申请请求
 38     abstract public function Apply(Request $_req);
 39 
 40 }
 41 
 42 //经理
 43 class CommonManager extends Manager
 44 {
 45     public function __construct($_name)
 46     {
 47         parent::__construct($_name);
 48     }
 49     public function Apply(Request $_req)
 50     {
 51         if($_req->requestType=="请假" && $_req->num<=2)
 52         {
 53             echo "{$this->name}:{$_req->requestContent} 数量{$_req->num}被批准。<br/>";
 54         }
 55         else
 56         {
 57             if(isset($this->manager))
 58             {
 59                 $this->manager->Apply($_req);
 60             }
 61         }
 62 
 63     }
 64 }
 65 
 66 //总监
 67 class MajorDomo extends Manager
 68 {
 69     public function __construct($_name)
 70     {
 71         parent::__construct($_name);
 72     }
 73 
 74     public function Apply(Request $_req)
 75     {
 76         if ($_req->requestType == "请假" && $_req->num <= 5)
 77         {
 78             echo "{$this->name}:{$_req->requestContent} 数量{$_req->num}被批准。<br/>";
 79         }
 80         else
 81         {
 82             if (isset($this->manager))
 83             {
 84                 $this->manager->Apply($_req);
 85             }
 86         }
 87 
 88     }
 89 }
 90 
 91 
 92 //总经理
 93 class GeneralManager extends Manager
 94 {
 95     public function __construct($_name)
 96     {
 97         parent::__construct($_name);
 98     }
 99 
100     public function Apply(Request $_req)
101     {
102         if ($_req->requestType == "请假")
103         {
104             echo "{$this->name}:{$_req->requestContent} 数量{$_req->num}被批准。<br/>";
105         }
106         else if($_req->requestType=="加薪" && $_req->num <= 500)
107         {
108             echo "{$this->name}:{$_req->requestContent} 数量{$_req->num}被批准。<br/>";
109         }
110         else if($_req->requestType=="加薪" && $_req->num>500)
111         {
112             echo "{$this->name}:{$_req->requestContent} 数量{$_req->num}再说吧。<br/>";
113         }
114     }
115 }

调用客户端代码:

 1 header("Content-Type:text/html;charset=utf-8");
 2 //--------------------职责链模式----------------------
 3 require_once "./Responsibility/Responsibility.php";
 4 $jingli = new CommonManager("李经理");
 5 $zongjian = new MajorDomo("郭总监");
 6 $zongjingli = new GeneralManager("孙总");
 7 
 8 //设置直接上级
 9 $jingli->SetHeader($zongjian);
10 $zongjian->SetHeader($zongjingli);
11 
12 //申请
13 $req1 = new Request();
14 $req1->requestType = "请假";
15 $req1->requestContent = "小菜请假!";
16 $req1->num = 1;
17 $jingli->Apply($req1);
18 
19 $req2 = new Request();
20 $req2->requestType = "请假";
21 $req2->requestContent = "小菜请假!";
22 $req2->num = 4;
23 $jingli->Apply($req2);
24 
25 $req3 = new Request();
26 $req3->requestType = "加薪";
27 $req3->requestContent = "小菜请求加薪!";
28 $req3->num = 500;
29 $jingli->Apply($req3);
30 
31 $req4 = new Request();
32 $req4->requestType = "加薪";
33 $req4->requestContent = "小菜请求加薪!";
34 $req4->num = 1000;
35 $jingli->Apply($req4);

适用场景:          

          1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。

          2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

         3、可动态指定一组对象处理请求。

 

posted @ 2018-03-26 17:51  范仁义  阅读(512)  评论(0编辑  收藏  举报