職責鏈模式(又叫責任鏈模式):
包含了一些命令對象和一些處理對象,每個處理對象決定它能處理那些命令對象,它也知道應該把自己不能處理的命令對象交下一個處理對象,該模式還描述了往該鏈添加新的處理對象的方法。
角色:
抽象處理者:定義出一個處理請求的介面。如果需要,介面可以定義出一個方法,以設定和返回對下家的引用。這個角色通常由一個抽象類別或介面實現。
具體處理者:具體處理者接到請求後,可以選擇將請求處理掉,或者將請求傳給下家。由於具體處理者持有對下家的引用,因此,如果需要,具體處理者可以訪問下家。
UML類圖:
適用情境:
1、有多個對象可以處理同一個請求,具體哪個對象處理該請求由運行時刻自動確定。
2、在不明確指定接收者的情況下,向多個對象中的一個提交一個請求。
3、可動態指定一組對象處理請求。
簡單的總結責任鏈模式,可以歸納為:
用一系列類(classes)試圖處理一個請求request,這些類之間是一個鬆散的耦合,唯一共同點是在他們之間傳遞request. 也就是說,來了一個請求,A類先處理,如果沒有處理,就傳遞到B類處理,如果沒有處理,就傳遞到C類處理,就這樣象一個鏈條(chain)一樣傳遞下去。
代碼實現:
name = $name; $this->requestContent = $requestContent; $this->reason = $reason; $this->num = $num; }}//抽象處理類,定義處理者具有的公用屬性和具體處理類需要實現的介面abstract class AbstractManager{ protected $name; //姓名 protected $position; //職位 protected $head; //上司 function __construct($name,$position){ $this->name = $name; $this->position = $position; } //設定上司 function setHead(AbstractManager $head){ $this->head = $head; } //處理申請 abstract function handleRequest(Request $request);}//具體處理類,經理,可以處理不多於7天的假期和不多於1000元的加薪請求class Director extends AbstractManager{ function __construct($name,$position){ parent::__construct($name,$position); } //處理申請 function handleRequest(Request $request){ if(($request->requestContent == "請假" && $request->num <7)||($request->requestContent == "加薪" && $request->num <1000) ){ return $request->name."的".$request->requestContent."請求已被".$this->name."批准."; }else{ //超過處理許可權轉給上級總監處理 if(isset($this->head)){ return $this->head->handleRequest($request); } } }}//具體處理類,總監,可以處理不多於15天的假期和不多於2000元的加薪請求class Majordomo extends AbstractManager{ function __construct($name,$position){ parent::__construct($name,$position); } //處理申請 function handleRequest(Request $request){ if(($request->requestContent == "請假" && $request->num <15)||($request->requestContent == "加薪" && $request->num <2000) ){ return $request->name."的".$request->requestContent."請求已被".$this->name."批准."; }else{ //超過處理許可權轉給上級總經理處理 if(isset($this->head)){ return $this->head->handleRequest($request); } } }}//具體處理類,總經理,可以處理請假和加薪請求class GeneralManager extends AbstractManager{ function __construct($name,$position){ parent::__construct($name,$position); } //處理申請 function handleRequest(Request $request){ if(($request->requestContent == "請假" && $request->num < 30)||($request->requestContent == "加薪" && $request->num <5000) ){ return $request->name."的".$request->requestContent."請求已被".$this->name."批准."; }else{ //沒有上級 return $request->name."的".$request->requestContent."請求已被".$this->name."否決!"; } }}//測試$generalManagerWang = new GeneralManager("王五","總經理");$majordomoLi = new Majordomo("李四","總監");$majordomoLi->setHead($generalManagerWang);$directZhang = new Director("張三","經理");$directZhang->setHead($majordomoLi);$request = new Request("葉良辰","請假","如果你有問題,可以隨時找我,良辰就喜歡對自以為是的人出手",100);$result = $directZhang->handleRequest($request); //葉良辰的請假請求已被王五否決!echo $result;