Chain of Responsibility Pattern是一种行为型设计模式,目的是在多个对象间处理请求时,达到解耦与组织的效果。此模式将多个对象连接成一条链,每个对象都有机会处理请求。当一个对像不能处理请求时,会将请求转发到下一个对象,直到能够处理或到达链的末端。
举例来说,有一个单位要向国家政府提出一个计划,计划分为四个阶段:初步的方案、详细的方案、执行的方案和结果的报告。每个阶段的负责人负责处理相关的工作,如果负责人无法处理该阶段的工作,则需要向下一个负责人传递请求,直到工作完成。
使用Chain of Responsibility Pattern可以有效地处理这个问题。我们可以将四个阶段的负责人连接成一条链,每个负责人都有处理该阶段工作的能力。如果一个负责人无法处理该阶段的工作,他会将请求传递给下一个负责人,直到该阶段的工作完成。
例如,初步的方案负责人无法处理详细方案的工作,因此他将请求传递给详细方案的负责人,如果详细方案的负责人无法处理,他会转发给执行方案的负责人,最终到达结果的报告负责人。此模式能够减少耦合并更容易维护,因为每个负责人都可以独立处理工作,而不必知道工作的详细情况或其他负责人的工作。
Chain of Responsibility 模式是一种行为型设计模式,通过组合对像形成一条链,每个对象都能够处理请求,若无法处理则传递给下一个对象。
可以通过该模式消除发送者和接收者之间的耦合关系,使得请求可以被多个对象处理。
Chain of Responsibility 模式应用于多个对象相互交互的场景,其中每个对象都可以根据需要动态处理请求,并且该模式能够优雅地处理复杂的请求处理过程。
该模式的优点包括:增强代码的复用性和灵活性,降低系统的耦合度,方便添加或删除处理者等。
该模式的缺点包括:链条过长可能会降低性能,并且由于链条中的每个对象都可以执行处理,因此可能会导致请求被重复处理。
在实现该模式时,需要定义一个抽像处理类,该类包含一个处理请求的方法以及设置下一个处理者的方法。同时还需要实现各个对象的具体处理逻辑。
答案:请参考以下范例Code
答案:请参考以下范例Code
答案:请参考以下范例Code
答案:请参考以下范例Code
答案:请参考以下范例Code
以下是范例Code:
例一.
interface Worker
{
public function setNext(Worker $worker);
public function handle($car);
}
class Inspector implements Worker
{
private $nextWorker;
public function setNext(Worker $worker)
{
$this->nextWorker = $worker;
}
public function handle($car)
{
if ($car->getProblemLevel() == ‘minor’)
{
echo “Inspector handles the car by repairing the problem directly.\n”;
$car->setProblemFixed();
}
else
{
$this->nextWorker->handle($car);
}
}
}
class Mechanic implements Worker
{
private $nextWorker;
public function setNext(Worker $worker)
{
$this->nextWorker = $worker;
}
public function handle($car)
{
if ($car->getProblemLevel() == ‘moderate’)
{
echo “Mechanic handles the car by repairing the problem.\n”;
$car->setProblemFixed();
}
else
{
$this->nextWorker->handle($car);
}
}
}
class SeniorTechnician implements Worker
{
public function setNext(Worker $worker)
{
// This is the last class in the chain
}
public function handle($car)
{
if ($car->getProblemLevel() == ‘complex’)
{
echo “Senior technician handles the car by repairing the problem.\n”;
$car->setProblemFixed();
}
else
{
echo “Sorry, we are unable to repair the problem.\n”;
$car->setProblemUnfixed();
}
}
}
class Car
{
private $problemLevel;
private $problemFixed = false;
public function __construct($problemLevel)
{
$this->problemLevel = $problemLevel;
}
public function getProblemLevel()
{
return $this->problemLevel;
}
public function setProblemFixed()
{
$this->problemFixed = true;
}
public function setProblemUnfixed()
{
$this->problemFixed = false;
}
public function isFixed()
{
return $this->problemFixed;
}
}
?>
使用范例:
输出结果:
Inspector handles the car by repairing the problem directly.
Is car1’s problem fixed? Yes.
Mechanic handles the car by repairing the problem.
Is car2’s problem fixed? Yes.
Senior technician handles the car by repairing the problem.
Is car3’s problem fixed? Yes.
例二.
interface Employee
{
public function setNext(Employee $employee);
public function work($food);
}
class Cashier implements Employee
{
private $nextEmployee;
public function setNext(Employee $employee)
{
$this->nextEmployee = $employee;
}
public function work($food)
{
echo “Cashier calculates the cost of the food.\n”;
$this->nextEmployee->work($food);
}
}
class Chef implements Employee
{
private $nextEmployee;
public function setNext(Employee $employee)
{
$this->nextEmployee = $employee;
}
public function work($food)
{
echo “Chef cooks the food according to the order.\n”;
$this->nextEmployee->work($food);
}
}
class Cleaner implements Employee
{
public function setNext(Employee $employee)
{
// This is the last class in the chain
}
public function work($food)
{
echo “Cleaner cleans up the table after the customer leaves.\n”;
}
}
?>
使用范例:
输出结果:
Cashier calculates the cost of the food.
Chef cooks the food according to the order.
Cleaner cleans up the table after the customer leaves.
例三.
interface Employee
{
public function setNext(Employee $employee);
public function work($patient);
}
class Receptionist implements Employee
{
private $nextEmployee;
public function setNext(Employee $employee)
{
$this->nextEmployee = $employee;
}
public function work($patient)
{
echo “Receptionist asks for patient’s basic information.\n”;
$this->nextEmployee->work($patient);
}
}
class Doctor implements Employee
{
private $nextEmployee;
public function setNext(Employee $employee)
{
$this->nextEmployee = $employee;
}
public function work($patient)
{
if ($patient->isSerious())
{
echo “Doctor diagnoses and sends the patient to the operating room.\n”;
}
else
{
echo “Doctor diagnoses and prescribes medicine for the patient.\n”;
}
}
}
class Surgeon implements Employee
{
public function setNext(Employee $employee)
{
// This is the last class in the chain
}
public function work($patient)
{
echo “Surgeon performs the surgery on the patient.\n”;
}
}
class Patient
{
private $isSerious;
public function __construct($isSerious)
{
$this->isSerious = $isSerious;
}
public function isSerious()
{
return $this->isSerious;
}
}
?>
使用范例:
输出结果:
Receptionist asks for patient’s basic information.
Doctor diagnoses and prescribes medicine for the patient.
Receptionist asks for patient’s basic information.
Doctor diagnoses and sends the patient to the operating room.
Surgeon performs the surgery on the patient.
例四.
interface Logger
{
public function setNext(Logger $logger);
public function log($level, $message);
}
class InformationLogger implements Logger
{
private $nextLogger;
public function setNext(Logger $logger)
{
$this->nextLogger = $logger;
}
public function log($level, $message)
{
if ($level == ‘information’)
{
echo “InformationLogger: $message\n”;
return true;
}
elseif (!is_null($this->nextLogger))
{
return $this->nextLogger->log($level, $message);
}
else
{
return false;
}
}
}
class WarningLogger implements Logger
{
private $nextLogger;
public function setNext(Logger $logger)
{
$this->nextLogger = $logger;
}
public function log($level, $message)
{
if ($level == ‘warning’)
{
echo “WarningLogger: $message\n”;
return true;
}
elseif (!is_null($this->nextLogger))
{
return $this->nextLogger->log($level, $message);
}
else
{
return false;
}
}
}
class ErrorLogger implements Logger
{
private $nextLogger;
public function setNext(Logger $logger)
{
$this->nextLogger = $logger;
}
public function log($level, $message)
{
if ($level == ’error’)
{
echo “ErrorLogger: $message\n”;
return true;
}
elseif (!is_null($this->nextLogger))
{
return $this->nextLogger->log($level, $message);
}
else
{
return false;
}
}
}
?>
使用范例:
输出结果:
InformationLogger: The system is starting up.
WarningLogger: The system has encountered an error.
ErrorLogger: The system has crashed.
例五.
interface ReviewHandler
{
public function setNext(ReviewHandler $handler);
public function handle($comment);
}
class BasicReviewHandler implements ReviewHandler
{
private $nextHandler;
public function setNext(ReviewHandler $handler)
{
$this->nextHandler = $handler;
}
public function handle($comment)
{
if ($comment->getLevel() == ‘basic’)
{
echo “Basic review is displayed directly.\n”;
}
elseif (!is_null($this->nextHandler))
{
$this->nextHandler->handle($comment);
}
else
{
echo “Sorry, your comment cannot be displayed.\n”;
}
}
}
class CertifiedReviewHandler implements ReviewHandler
{
private $nextHandler;
public function setNext(ReviewHandler $handler)
{
$this->nextHandler = $handler;
}
public function handle($comment)
{
if ($comment->getLevel() == ‘certified’)
{
echo “Certified review has to be approved before being displayed.\n”;
}
elseif (!is_null($this->nextHandler))
{
$this->nextHandler->handle($comment);
}
else
{
echo “Sorry, your comment cannot be displayed.\n”;
}
}
}
class ProReviewHandler implements ReviewHandler
{
private $nextHandler;
public function setNext(ReviewHandler $handler)
{
$this->nextHandler = $handler;
}
public function handle($comment)
{
if ($comment->getLevel() == ‘pro’)
{
echo “Pro review is sent to a specialist for reply.\n”;
}
elseif (!is_null($this->nextHandler))
{
$this->nextHandler->handle($comment);
}
else
{
echo “Sorry, your comment cannot be displayed.\n”;
}
}
}
class Comment
{
private $level;
public function __construct($level)
{
$this->level = $level;
}
public function getLevel()
{
return $this->level;
}
}
?>
使用范例:
输出结果:
Basic review is displayed directly.
Certified review has to be approved before being displayed.
Pro review is sent to a specialist for reply.