Chain of Responsibility Patterns
GoF定义:通过让多个(超过一个)对象来处理请求实现请求发送者和接收者的耦合度。接收者(对象)的链会被传入请求,直到有一个对象处理此请求
概念
这里按序列方式处理对象,会有一个源来执行这个过程。我们会创建一个接收链,其中的每个对象都有逻辑来处理不同类型的命令对象。在一个处理过程完成后,如果这个对象并没有被处理完成,那么将这个对象发送到接收链的下一个对象。我们可以在任何时候从链尾添加对象
例子
现实世界:在一个企业中,有客服会将用户的反馈收集起来给到对应的部门,并不是每个部门都直接处理问题,当他们确定了问题的性质之后,会继续把问题抛向更适合解决的部门
代码世界:假设有一个应用处理电子邮件和传真,对应各有一个错误的处理器(handler),它们只会处理对应的错误而不关心其它类型的错误。我们会将这两个handler连在一起,如果发现新类型的错误处理器,可以将其连在后面。这个链路会在请求被解决或者链路终结时停止
展示

代码
public class ChainOfResponsibilityPatternEx
{
public static void main(String[] args)
{
System.out.println("***Chain of Responsibility Pattern Demo***\n");
//Making the chain first: IssueRaiser->FaxErrorhandler->EmailErrorHandler
IReceiver faxHandler, emailHandler;
//end of chain
emailHandler = new EmailErrorHandler(null);
//fax handler is before email
faxHandler = new FaxErrorHandler(emailHandler);
//starting point: raiser will raise issues and set the first handler
IssueReceiver raiser = new IssueReceiver (faxHandler);
Message m1 = new Message("Fax is reaching late to the destination", MessagePriority.Normal);
Message m2 = new Message("Email is not going", MessagePriority.High);
Message m3 = new Message("In Email, BCC field is disabled occasionally", MessagePriority.Normal);
Message m4 = new Message("Fax is not reaching destination", MessagePriority.High);
raiser.raiseMessage(m1);
raiser.raiseMessage(m2);
raiser.raiseMessage(m3);
raiser.raiseMessage(m4);
}
}
enum MessagePriority
{
Normal, High
}
class Message
{
public String text;
public MessagePriority priority;
public Message(String text, MessagePriority priority)
{
this.text = text;
this.priority = priority;
}
}
interface IReceiver
{
Boolean processMessage(Message message);
}
class IssueReceiver
{
public IReceiver setFirstReceiver;
public IssueReceiver(IReceiver setFirstReceiver)
{
this.setFirstReceiver = setFirstReceiver;
}
public void raiseMessage(Message message)
{
if (setFirstReceiver != null)
{
setFirstReceiver.processMessage(message);
}
}
}
class FaxErrorHandler implements IReceiver
{
private IReceiver nextReceiver;
public FaxErrorHandler(IReceiver nextReceiver)
{
this.nextReceiver = nextReceiver;
}
@Override
public Boolean processMessage(Message message)
{
if (message.text.contains("Fax"))
{
System.out.println("FaxErrorHandler processed "+ message.priority+ "priority issue: "+ message.text);
return true;
}
else
{
if (nextReceiver != null)
{
nextReceiver.processMessage(message);
}
}
return false;
}
}
class EmailErrorHandler implements IReceiver
{
private IReceiver nextReceiver;
public EmailErrorHandler(IReceiver nextReceiver)
{
this.nextReceiver = nextReceiver;
}
@Override
public Boolean processMessage(Message message)
{
if (message.text.contains("Email"))
{
System.out.println("EmailErrorHandler processed "+ message.priority + "priority issue: "+ message.text);
return true;
}
else
{
if (nextReceiver != null)
{
nextReceiver.processMessage(message);
}
}
return false;
}
}
Note
- 当我们在不指定接收者的情况下发送了请求,并且希望任意一个接收者可以处理这个请求,此时可以使用这个模式
- 在有多个接收者可以处理某个请求,但是接收者不知道优先级的情况下,我们可以使用这个模式来解决此问题
- 运行时处理某个对象(请求)的能力
- 可以定义新链,也可以扩展旧链
- 有时我们希望有一个自动转发请求的机制,而不需要自己写特定的转发规则(Smalltalk’s doesnotUnderstand是一个典型例子--有时间看过之后再来补充)
思考
这个模式的用法基本上上一节书里都说完了,我个人感觉这个模式的核心在于请求必须是多种(3、4种及以上)类型的值得使用这个模式
浙公网安备 33010602011771号