设计模式 | 职责链模式(Chain of responsibility)
定义:
使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连城一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
结构:(书中图,侵删)
一个抽象的处理者
若干个具体处理者(每个具体处理者都不知道它的继任者是谁,这个继任者由客户端决定,只负责把处理不了的请求转发给继任者)
实例:
工作流基本都可以用这个模式来设计。
我就来写个生产酱板鸭的流水线好了。
屠宰-》清洗-》卤制-》风干-》包装
简化一点,懒得写那么多类
清洗-》卤制-》包装
鸭子类:
package designpattern.chainofresponsibility; public class Duck { public State state; Duck(State state) { this.state = state; } public enum State { DIRTY, CLEAN, COOKED, PACKAGED } public State getState() { return state; } public void setState(State state) { this.state = state; } }
抽象处理者类:
package designpattern.chainofresponsibility; public abstract class Handler { protected Handler successor; public void setSuccessor(Handler successor) { this.successor = successor; } public abstract void handleDuck(Duck duck); }
清洗者类(具体处理者):
package designpattern.chainofresponsibility; import designpattern.chainofresponsibility.Duck.State; public class DuckCleaner extends Handler { @Override public void handleDuck(Duck duck) { if (duck.state == State.DIRTY) { System.out.println("清洗员-》清理鸭子~"); duck.setState(State.CLEAN); } else { successor.handleDuck(duck); } } }
厨师类(具体处理者):
package designpattern.chainofresponsibility; import designpattern.chainofresponsibility.Duck.State; public class DuckCook extends Handler { @Override public void handleDuck(Duck duck) { if (duck.state == State.CLEAN) { System.out.println("厨师-》卤制鸭子~"); duck.setState(State.COOKED); } else { successor.handleDuck(duck); } } }
打包者类(具体处理者):
package designpattern.chainofresponsibility; import designpattern.chainofresponsibility.Duck.State; public class DuckPackager extends Handler { @Override public void handleDuck(Duck duck) { if (duck.state == State.COOKED) { System.out.println("打包员-》包装鸭子~"); duck.setState(State.PACKAGED); } } }
客户端:
package designpattern.chainofresponsibility; import designpattern.chainofresponsibility.Duck.State; public class Client { public static void main(String[] args) { DuckCleaner duckCleaner = new DuckCleaner(); DuckCook duckCook = new DuckCook(); DuckPackager duckPackager = new DuckPackager(); duckCleaner.setSuccessor(duckCook); duckCook.setSuccessor(duckPackager); // 处理脏鸭子 Duck duck = new Duck(State.DIRTY); duckCleaner.handleDuck(duck); // 处理卤好的鸭子 duck.setState(State.COOKED); duckCleaner.handleDuck(duck); } }
结果输出:
清洗员-》清理鸭子~
打包员-》包装鸭子~
不管鸭子在哪个状态,统统传给清理者,他处理不了,会一路传下去,直到正确的人来处理。
总结:
这个模式算是一个结构比较简单的,也很好理解,只不过之前自己想的时候完全没有想出来可以用这样的方式来实现。
又能把请求传递下去又能让处理者之间,以及处理者和客户端之间解耦,真的很巧妙。
不过像上面说的,继任者是由客户端决定的,但实际上具体处理者之间有潜在的逻辑关系,如果客户端没有正确的设置链条可能会导致请求得不到处理。
比如上面的例子,直接拿洗好的鸭子去包装显然是包装不了的。
所以需要把文档写得足够清晰,以供客户端正确使用。