B5:責任鏈模式 Chain Of Responsibility
阿新 • • 發佈:2017-11-06
con 出錯 耦合 idt uml fun .com function width
使多個對象都有機會處理處理請求,從而避免請求的發送者和接受者之間的耦合關系.將這個對象連成一條鏈,並沿著該鏈處理請求,直到有一個對象能夠處理它為止.
UML
示例代碼:
abstract class Handle { protected $nextHandle; public function setNextHandle(Handle $handle) { $this->nextHandle = $handle; } abstract public function handleRequest($level); } class Handle1 extends Handle { public function handleRequest($level) { if ($level > 0 && $level < 10) { echo ‘Handle1 處理了‘; } elseif(!is_null($this->nextHandle)) { $this->nextHandle->handleRequest($level); } } } class Handle2 extends Handle { public function handleRequest($level) { if ($level > 10 && $level < 100) { echo ‘Handle2 處理了‘; } elseif(!is_null($this->nextHandle)) { $this->nextHandle->handleRequest($level); } } } class Handle3 extends Handle { public function handleRequest($level) { if ($level > 100 && $level < 1000) { echo ‘Handle3 處理了‘; } elseif(!is_null($this->nextHandle)) { $this->nextHandle->handleRequest($level); } } } $handle1 = new Handle1(); $handle2 = new Handle2(); $handle3 = new Handle3(); $handle1->setNextHandle($handle2); $handle2->setNextHandle($handle3); $handle1->handleRequest(600);
這個手動設置下一處理者,還是有點不方便.有時候設置出錯,容易導致死循環,我們改進一下.
示例代碼:
abstract class Handle { abstract public function handleRequest($level); } class Handle1 extends Handle { public function handleRequest($level) { if ($level > 0 && $level < 10) { echo ‘Handle1 處理了‘; return true; } } } class Handle2 extends Handle { public function handleRequest($level) { if ($level > 10 && $level < 100) { echo ‘Handle2 處理了‘; return true; } } } class Handle3 extends Handle { public function handleRequest($level) { if ($level > 100 && $level < 1000) { echo ‘Handle3 處理了‘; return true; } } } class Context { protected $chains = []; public function addHandle(Handle $handle) { $this->chains[] = $handle; } public function handleRequest($level) { foreach ($this->chains as $handler) { if ($handler->handleRequest($level)) { break; } } } } $context = new Context(); $context->addHandle(new Handle1()); $context->addHandle(new Handle2()); $context->addHandle(new Handle3()); $context->handleRequest(600);
我們將鏈的設置交給Context,Context維護了一個數組來保存設置的處理者.context中的handleRequest方法,循環從數組中讀取並處理.在每個處理者類中,我們讓其如果有處理,就返回true,在foreach循環中跳出循環,防止無用的循環繼續下去.
當然有時候我們需要職責鏈的每個處理者挨個處理請求,也可以使用這種方法.
B5:責任鏈模式 Chain Of Responsibility