更加便于扩展的职责链模式实例

为职责链模式定义统一的业务对象接口和控制接口有便于扩展已有的业务程序。

<?php
	class RequestModel{
		/**
		 * 表示具体的业务类型 
		 */
		protected $type;
		/**
		 * 通过构造方法把具体的业务类型传递进来
		 * @param type 具体的业务类型
		 */
		public function __construct($type){
			$this->type = $type;
		}
		
		public function getType(){
			return $this->type;
		}
	}
	
	/**
	 * 定义职责对象的接口
	 */
	abstract  class Handler{
		/**
		 * 持有下一个处理请求的对象
		 */
		protected $successor = null;
		/**
		 * 设置下一个处理对象的方法
		 * @param successor 下一个处理对象
		 */
		public function setSuccessor($successor){
			$this->successor = $successor;
		}
		/**
		 * 通用的请求处理方法
		 * @param rm 通用的请求对象
		 * @return  处理后需要返回的对象
		 */
		public function handleRequest($rm){
			if($this->successor != null){
				//这个是默认的实现,如果子类不愿意处理这个请求
				//那就传递到下一个职责对象去处理
				return $this->successor->handleRequest($rm);
			}
			else{
				echo "没有后续处理或者暂时不支持这样的功能处理";
				return false;
			}
		}
	}
	
	/**
	 * 封装和聚餐费用申请业务相关的请求数据
	 */
	class FeeRequestModel extends RequestModel{
		/**
		 * 约定具体的业务类型
		 */
		public static $FEE_TYPE = "fee";
		
		public function __construct(){
			parent::__construct(FeeRequestModel::$FEE_TYPE);
		}
		
		/**
		 * 申请人
		 */
		private $user;
		/**
		 * 申请金额
		 */
		private $fee;
		
		/**
		 * 相应的SET/GET方法实现
		 */
		function __get($property_name)
		{
			if(isset($this->$property_name)){
				return($this->$property_name);
			}
			else{
				return(NULL);
			}
		}
		//__set()方法用来设置私有属性
		function __set($property_name, $value)
		{
			$this->$property_name = $value;
		}
	}
	
	/**
	 * 实现项目经理处理聚餐费用申请的请求
	 */
	class ProjectManager extends Handler{
		public function handleRequest($rm){
			
			if(FeeRequestModel::$FEE_TYPE == $rm->type){
				//表示聚餐费用申请
				return $this->handleFeeRequest($rm);
			}
			else{
				return parent::handleRequest($rm);
			}
		}
		
		private function handleFeeRequest($rm){
			//先把通用的对象造型回来
			if($rm instanceof FeeRequestModel){
				$frm = $rm;
				//项目经理的权限比较小,只能在500以内
				if($frm->fee < 500){
					if($frm->user === 'xl'){
						$str = "项目经理同意".$frm->user."的聚餐费用申请".$frm->fee."元";
					}
					else{
						//其他人一律不同意
						$str = "项目经理不同意".$frm->user."的聚餐费用申请".$frm->fee."元";
					}
					return $str;
				}
				else{
					return $this->successor->handleRequest($rm);
				}
			}
			else{
				return "不接受处理非餐费申请的工作";
			}
		}
	}
	
		/**
	 * 实现部门经理处理聚餐费用申请的请求
	 */
	class DepManager extends Handler{
		public function handleRequest($rm){
			if(FeeRequestModel::$FEE_TYPE == $rm->type){
				//表示聚餐费用申请
				return $this->handleFeeRequest($rm);
			}
			else{
				return parent::handleRequest($rm);
			}
		}
		
		private function handleFeeRequest($rm){
			//先把通用的对象造型回来
			if($rm instanceof FeeRequestModel){
				$frm = $rm;
				//项目经理的权限比较小,只能在500以内
				if($frm->fee >= 500){
					if($frm->user === 'xl'){
						$str = "部门经理同意".$frm->user."的聚餐费用申请".$frm->fee."元";
					}
					else{
						//其他人一律不同意
						$str = "部门经理不同意".$frm->user."的聚餐费用申请".$frm->fee."元";
					}
					return $str;
				}
				else{
					return $this->successor->handleRequest($rm);
				}
			}
			else{
				return "不接受处理非餐费申请的工作";
			}
		}
	}
	
	/**
	 * 现在我们来扩展一个新的费用申请功能,差旅费
	 * 这里所有的参数都差不多,这是为了简单,实际中是 不一样的
	 */
	class PreFeeRequestModel extends RequestModel{
		/**
		 * 约定具体的业务类型
		 */
		public static $FEE_TYPE = "preFee";
		
		public function __construct(){
			parent::__construct(PreFeeRequestModel::$FEE_TYPE);
		}
		
		/**
		 * 申请人
		 */
		private $user;
		/**
		 * 申请金额
		 */
		private $fee;
		
		/**
		 * 相应的SET/GET方法实现
		 */
		function __get($property_name)
		{
			if(isset($this->$property_name)){
				return($this->$property_name);
			}
			else{
				return(NULL);
			}
		}
		//__set()方法用来设置私有属性
		function __set($property_name, $value)
		{
			$this->$property_name = $value;
		}
	}

	/**
	 * 现在我们来扩展相应的职责链类对象
	 */
	class ProjectManager2 extends ProjectManager{
		public function handleRequest($rm){
			if(PreFeeRequestModel::$FEE_TYPE == $rm->type){
				return $this->handlePreFeeRequest($rm);
			}
			else{
				//如果不是这个新扩充的功能,那么交给父类,看看父类中有没有处理这种业务的逻辑
				return parent::handleRequest($rm);
			}
		}
		//处理差旅费
		private function handlePreFeeRequest($rm){
			
			//先把通用的对象造型回来
			if($rm instanceof PreFeeRequestModel){
				$frm = $rm;
				//项目经理的权限比较小,只能在500以内
				if($frm->fee < 5000){
					if($frm->user === 'xl'){
						$str = "项目经理同意".$frm->user."的差旅费用申请".$frm->fee."元";
					}
					else{
						//其他人一律不同意
						$str = "项目经理不同意".$frm->user."的差旅费用申请".$frm->fee."元";
					}
					return $str;
				}
				else{
					return $this->successor->handleRequest($rm);
				}
			}
			else{
				return "不接受处理非餐费申请的工作";
			}
		}		
	}
	
	class DepManager2 extends DepManager{
		public function handleRequest($rm){
			if(PreFeeRequestModel::$FEE_TYPE == $rm->type){
				return $this->handlePreFeeRequest($rm);
			}
			else{
				//如果不是这个新扩充的功能,那么交给父类,看看父类中有没有处理这种业务的逻辑
				return parent::handleRequest($rm);
			}
		}
		//处理差旅费
		private function handlePreFeeRequest($rm){
			//先把通用的对象造型回来
			if($rm instanceof PreFeeRequestModel){
				$frm = $rm;
				//项目经理的权限比较小,只能在500以内
				if($frm->fee >= 5000){
					if($frm->user === 'xl'){
						$str = "部门经理同意".$frm->user."的差旅费用申请".$frm->fee."元";
					}
					else{
						//其他人一律不同意
						$str = "部门经理不同意".$frm->user."的差旅费用申请".$frm->fee."元";
					}
					return $str;
				}
				else{
					return $this->successor->handleRequest($rm);
				}
			}
			else{
				return "不接受处理非餐费申请的工作";
			}
		}		
	}	
	
	//先要组装职责链
	$h1 = new ProjectManager2();
	$h2 = new DepManager2();
	
	$h1->setSuccessor($h2);
	
	//先测试聚餐服用
	$frm = new FeeRequestModel();
	$frm->user = "xl";
	$frm->fee = 700;
	
	echo $h1->handleRequest($frm)."<br>";
	
	//接下来我们测试一下差旅费
	$prm = new PreFeeRequestModel();
	$prm->user = 'xl';
	$prm->fee = 6000;
	echo $h1->handleRequest($prm);
	
	
	
?>

你可能感兴趣的:(PHP,职责链)