职责链模式(Chain of Responsibility Pattern):避免请求发送者与接受者耦合一起。把全部有可能接受请求的对象连接成一条链,并沿着这条链传递请求,知道有对象处理该请求为止。
假设有一个需求,当用户咨询客服时,需要根据用户的年龄提供不同的客服人员,先看一下传统的处理方式,下面是伪代码:
Handler 类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| public class PersonRequestHandler { private Person person;
public PersonRequestHandler(Person person) { this.person = person; }
public void handle() { int age = this.person.getAge(); if (age < 5) { handleForChild(); } else if (age < 23) { handleForYouth(); } else if (age < 60) { handleForAdult(); } else { handleForOld(); } }
private void handleForOld() { LogUtils.i("doSomething For Old"); }
private void handleForAdult() { LogUtils.i("doSomething For Adult");
}
private void handleForYouth() { LogUtils.i("doSomething For Youth");
}
private void handleForChild() { LogUtils.i("doSomething For Chile"); } }
|
用这样的方式完全可以处理这个需求,但是只停留在完成需求这个阶段远远不够,这种方式有几个问题:
- 如果需要更细分年龄段 Handler 类会变的异常庞大,不易阅读和维护
- 所有的处理都放在该类中,违反了单一职责原则
- 如果需要增删处理方式,就需要修改该类,又违反了开闭原则
职责链模式的出现解决了上述的几个问题,先来看职责链模式的结构图:
下面是利用职责链模式处理上面需求的伪代码:
Handler 类:
1 2 3 4 5 6 7 8 9 10
| public abstract class Handler {
protected Handler successor;
public void setSuccessor(Handler successor) { this.successor = successor; }
public abstract void handleRequest(Person person); }
|
ConcreteHandler 类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| public class Child extends Handler { @Override public void handleRequest(Person person) { if (person.getAge() < 5) { LogUtils.i("doSomething For Child"); } else { this.successor.handleRequest(person); } } }
public class Youth extends Handler { @Override public void handleRequest(Person person) { if (person.getAge() < 23) { LogUtils.i("doSomething For Youth"); } else { this.successor.handleRequest(person); } } }
public class Adult extends Handler { @Override public void handleRequest(Person person) { if (person.getAge() < 60) { LogUtils.i("doSomething For Adult"); } else { this.successor.handleRequest(person); } } }
public class Old extends Handler { @Override public void handleRequest(Person person) { LogUtils.i("doSomething For Old"); } }
|
这种属于纯的职责链模式,ConcreteHandler 对象只能在处理和不处理两个行为中选择一个
如果是不纯的职责链模式是允许在处理请求时只处理一部分,然后继续往下家发送该请求;也可以全部处理完成后,再往下家发送;同时也允许该请求不被任何 ConCreteHandler 对象接收并处理
优点
职责链模式使得一个对象无须知道是其他哪一个对象处理其请求,对象仅需知道该请求会被处理即可,接收者和发送者都没有对方的明确信息,且链中的对象不需要知道链的结构,由客户端负责链的创建,降低了系统的耦合度
在给对象分派职责时,职责链可以给我们更多的灵活性,可以通过在运行时对该链进行动态的增加或修改来增加或改变处理一个请求的职责
在系统中增加一个新的具体请求处理者时无须修改原有系统的代码,只需要在客户端重新建链即可,符合开闭原则
缺点
适用场景
评论