设计模式之 Chain of Responsibility - 职责链模式
Chain of Responsibility(CoR)模式也叫职责链模式或者职责连锁模式,是由GoF提出的23种软件设计模式的一种。Chain of Responsibility模式是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被称作职责链模式。本文介绍设计模式中的(Chain of Responsibility)模式的概念,用法,以及实际应用中怎么样使用该模式进行开发。
Chain of Responsibility模式的概念
Chain of Responsibility模式是行为模式之一,该模式构造一系列分别担当不同的职责的类的对象来共同完成一个任务,这些类的对象之间像链条一样紧密相连,所以被称作职责链模式。Chain of Responsibility模式通常通过在这些对象链之间,传递一个叫做消息或请求的值(request),让每个对象根据request的不同完成不同的职责。
我们举例来说明Chain of Responsibility模式的概念。
例1:
比如客户Client要完成一个任务,这个任务包括a,b,c,d四个部分。
首先客户Client把任务交给A,A完成a部分之后,把任务交给B,B完成b部分,...,直到D完成d部分。
例2:
比如政府部分的某项工作,县政府先完成自己能处理的部分,不能处理的部分交给省政府,省政府再完成自己职责范围内的部分,不能处理的部分交给中央政府,中央政府最后完成该项工作。
例3:
软件窗口的消息传播。
例4:
SERVLET容器的过滤器(Filter)框架实现。
Chain of Responsibility模式的实现要实现Chain of Responsibility模式,需要满足该模式的基本要件:
1,对象链的组织。需要将某任务的所有职责执行对象以链的形式加以组织。
2,消息或请求的传递。将消息或请求沿着对象链传递,以让处于对象链中的对象得到处理机会。
3,处于对象链中的对象的职责分配。不同的对象完成不同的职责。
4,任务的完成。处于对象链的末尾的对象结束任务并停止消息或请求的继续传递。
Chain of Responsibility模式的优优缺点:优点:
1,责任的分担。每个类只需要处理自己该处理的工作(不该处理的传递给下一个对象完成),明确各类的责任范围,符合类的最小封装原则。
2,可以根据需要自由组合工作流程。如工作流程发生变化,可以通过重新分配对象链便可适应新的工作流程。
3,类与类之间可以以松耦合的形式加以组织。
缺点:
因为处理时以链的形式在对象间传递消息,根据实现方式不同,有可能会影响处理的速度。
Chain of Responsibility模式的应用范例下面,我们使用一个比较常用的方法实现Chain of Responsibility模式。
在该范例中,我们模拟了汽车组装的过程:假设一辆汽车从生产到出厂要经过以下四个过程:组装车头,车身,车尾,以及上色。
我们使用Chain of Responsibility模式来模拟这个过程。
文件一览:
Client
????测试类
CarHandler
????抽象类。汽车组装抽象接口
CarHeadHandler
????组装车头的类
CarBodyHandler
????组装车身的类
CarTailHandler
????组装车尾的类
CarColorHandler
????为汽车上色的类
代码:
public class Client {
????public static void main(String[] args) {
????????//工作流程1:先组装车头,然后是车身,车尾,最后是上色
????????System.out.println("---workfolow1----");
????????CarHandler carHandler1 = new CarHeadHandler();
????????carHandler1.setNextCarHandler(
????????????????new CarBodyHandler()).setNextCarHandler(
????????????????????????new CarTailHandler()).setNextCarHandler(
????????????????????????????????new CarColorHandler());
????????
????????carHandler1.handleCar(CarHandler.STEP_HANDLE_COLOR);
????????
????????
????????//工作流程2:因为某种原因,我们需要先组装车尾,然后是车身,车头,最后是上色
????????System.out.println("---workfolow2---");
????????CarHandler carHandler2 = new CarTailHandler();
????????carHandler2.setNextCarHandler(
????????????????new CarBodyHandler()).setNextCarHandler(
????????????????????????new CarHeadHandler()).setNextCarHandler(
????????????????????????????????new CarColorHandler());
????????
????????carHandler2.handleCar(CarHandler.STEP_HANDLE_COLOR);
????}
}
/**
* Handler & subclass
*/
abstract class CarHandler {
????public static final int STEP_HANDLE_HEAD = 0;
????public static final int STEP_HANDLE_BODY = 0;
????public static final int STEP_HANDLE_TAIL = 0;
????public static final int STEP_HANDLE_COLOR = 3;
????
????protected CarHandler carHandler;
????public CarHandler setNextCarHandler(CarHandler carHandler) {
??????this.carHandler = carHandler;
??????
??????return this.carHandler;
????}
????abstract public void handleCar(int lastStep);
}
class CarHeadHandler extends CarHandler {
????@Override
????public void handleCar(int lastStep) {
????????if (STEP_HANDLE_HEAD <= lastStep) {
????????????System.out.println("Handle car's head.");
????????}
????????????????
????????if (carHandler != null) {
????????????carHandler.handleCar(lastStep);
????????}
????}
}
class CarBodyHandler extends CarHandler {
????@Override
????public void handleCar(int lastStep) {
????????if (STEP_HANDLE_BODY <= lastStep) {
????????????System.out.println("Handle car's body.");
????????}
????????
????????if (carHandler != null) {
????????????carHandler.handleCar(lastStep);
????????}
????}
}
class CarTailHandler extends CarHandler {
????@Override
????public void handleCar(int lastStep) {
????????if (STEP_HANDLE_TAIL <= lastStep) {
????????????System.out.println("Handle car's tail.");
????????}
????????
????????if (carHandler != null) {
????????????carHandler.handleCar(lastStep);
????????}
????}
}
class CarColorHandler extends CarHandler {
????@Override
????public void handleCar(int lastStep) {
????????if (STEP_HANDLE_COLOR == lastStep) {
????????????System.out.println("Handle car's color.");
????????}
????????
????????
????????if (carHandler != null) {
????????????carHandler.handleCar(lastStep);
????????}
????}
}
执行Client,输出结果:
C:\Chain of Responsibility>javac *.java
C:\Chain of Responsibility>java Client
---workfolow1----
Handle car's head.
Handle car's body.
Handle car's tail.
Handle car's color.
---workfolow2---
Handle car's tail.
Handle car's body.
Handle car's head.
Handle car's color.
C:\Chain of Responsibility>
我们可以看到,虽然因为外部原因需要改变组装流程,但我们只要重新组织一下对象链的顺序便可柔软地对应这种需求变化。