天天看點

設計模式之行為型模式—— 3.5 職責鍊模式

<?php

	/**
	 * 3.5 職責鍊模式
	 * 	定義:
	 * 		使多個對象都有機會處理請求,進而避免請求的
	 * 		發送者和接受者直接的耦合關系。将這個對象連
	 * 		成一條鍊,并沿着這條鍊傳遞該請求,直到有一
	 * 		個對象處理它為止。
	 * 	角色:
	 * 		1. 抽象Handler類
	 * 			職責:定義一個處理請示的接口。
	 * 		2. 具體Handler類
	 * 			職責:具體處理者類,處理它所負責的請求
	 * 				  ,它可通路它的後繼者,如果可處理
	 * 				  該請求,就處理之,否則就将該請求
	 * 				  轉發給它的後繼者。
	 *
	 * 	優點:
	 * 		1. 增強了系統的可擴充性;
	 * 		2. 是可以避免過多的if或if-else語句;
	 * 		3. 減小了對象之間的耦合性;
	 * 		4. 可以根據需要自由組合工作流程。如工作流程
	 * 		   發生變化,可以通過重新配置設定對象鍊便可适應
	 * 		   新的工作流程;
	 * 		5. 責任分擔。每個類隻需處理自己該處理的工作
	 * 		   (不該處理的傳遞給下一個對象完成),明确
	 * 		   各類的責任範圍,符合單一職責原則。
	 * 		
	 * 	缺點:
	 * 		1. 使用此模式時會産生多處理者對象,但實際使
	 * 		   用的處理者對象卻隻有一個,這在某種程度講
	 * 		   是資源的浪費。
	 * 		2. 職責鍊建立的合理性要靠用戶端來保證,增加
	 * 		   了程式的複雜性,也有可能由于職責鍊導緻出
	 * 		   錯。
	 * 		   
	 * 	使用場景:
	 * 		1. 有多個對象可以處理一個請求,具體是哪個對象
	 * 		   處理該請求運作時自動确定。
	 * 		2. 你想在不明确指定接受者的情況下,向多個對象
	 * 		   中的一個送出一個請求。
	 * 		3. 可處理一個請求的對象集合應被動态指定。
	 */

	//抽象Handler類
	abstract class Handler{
		protected $successor;
		public function setSuccessor(Handler $successor){
			$this->successor=$successor;
		}
		abstract public function handlerRequest($request);
	}
	//具體Handler類
	class ConcreteHandler1 extends Handler{
		public function handlerRequest($request){
			if($request >= 0 && $request < 10){
				echo get_class($this).'處理請求'.$request;
			}else if($this->successor != null){
				$this->successor->handlerRequest($request);
			}
		}
	}
	class ConcreteHandler2 extends Handler{
		public function handlerRequest($request){
			if($request >= 10 && $request < 20){
				echo get_class($this).'處理請求'.$request;
			}else if($this->successor != null){
				$this->successor->handlerRequest($request);
			}
		}
	}
	class ConcreteHandler3 extends Handler{
		public function handlerRequest($request){
			if($request >= 20 && $request < 30){
				echo get_class($this).'處理請求'.$request;
			}else if($this->successor != null){
				$this->successor->handlerRequest($request);
			}
		}
	}

	//用戶端
	//生成請求的具體處理對象
	$h1=new ConcreteHandler1();
	$h2=new ConcreteHandler2();
	$h3=new ConcreteHandler3();
	//設定處理對象的下一個負責人(即處理請求的對象)
	$h1->setSuccessor($h2);
	$h2->setSuccessor($h3);
	//具體的請求有職責鍊的第一個接收
	$h1->handlerRequest(20);
?>      

繼續閱讀