书本的原句:
使多个对象都有几乎处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条连传递改请求,直到有一个对象处理它为止。
例子:一个员工请假或申请加薪需要先后通过小经理=》大经理=》最大的boss的审核,只有在最大boss审核通过后,申请才算生效:
public class Main {
public static void main(String[] args) {
Manager smallManager = new SmallManager("小经理");
Manager bigManager = new BigManager("大经理");
Manager boss = new Boss("最大的Boss");
//设置上级
smallManager.setManager(bigManager);
bigManager.setManager(boss);
Request request_1 = new Request("请假", 10);
Request request_2 = new Request("请假", 2);
smallManager.doCheck(request_1);
System.out.println("---------------------");
smallManager.doCheck(request_2);
System.out.println("---------------------");
Request request_3 = new Request("加薪", 100);
Request request_4 = new Request("加薪", 10000);
smallManager.doCheck(request_3);
System.out.println("---------------------");
smallManager.doCheck(request_4);
}
}
class Request {
private String type;
private int value;
public Request(String type, int value) {
this.type = type;
this.value = value;
}
public String getType() {
return type;
}
public int getValue() {
return value;
}
}
abstract class Manager {
protected String name;
protected Manager manager;
public Manager(String name) {
this.name = name;
}
public void setManager(Manager manager) {
this.manager = manager;
}
abstract void doCheck(Request request);
}
class SmallManager extends Manager{
public SmallManager(String name) {
super(name);
}
@Override
void doCheck(Request request) {
if ( "请假".equals(request.getType()) && request.getValue() > 5 ){
System.out.println(name + ":请假不能超过5天");
return;
}
System.out.println("类型:"+request.getType()+",数值:"+request.getValue()+","+name+"审核通过了");
if (null != manager)
manager.doCheck(request);
}
}
class BigManager extends Manager{
public BigManager(String name) {
super(name);
}
@Override
void doCheck(Request request) {
if ( "请假".equals(request.getType()) && request.getValue() > 3 ){
System.out.println(name + ":请假不能超过3天");
return;
}
System.out.println("类型:"+request.getType()+",数值:"+request.getValue()+","+name+"审核通过了");
if (null != manager)
manager.doCheck(request);
}
}
class Boss extends Manager{
public Boss(String name) {
super(name);
}
@Override
void doCheck(Request request) {
if ( "请假".equals(request.getType()) && request.getValue() > 2 ){
System.out.println(name + ":请假不能超过2天");
return;
} else if ( "加薪".equals(request.getType()) && request.getValue() > 1000){
System.out.println(name + ":加薪1000块以上太高了,以后再说");
return;
}
System.out.println("类型:"+request.getType()+",数值:"+request.getValue()+","+name+"审核通过了");
if (null != manager)
manager.doCheck(request);
}
}
小经理:请假不能超过5天
---------------------
类型:请假,数值:2,小经理审核通过了
类型:请假,数值:2,大经理审核通过了
类型:请假,数值:2,最大的Boss审核通过了
---------------------
类型:加薪,数值:100,小经理审核通过了
类型:加薪,数值:100,大经理审核通过了
类型:加薪,数值:100,最大的Boss审核通过了
---------------------
类型:加薪,数值:10000,小经理审核通过了
类型:加薪,数值:10000,大经理审核通过了
最大的Boss:加薪1000块以上太高了,以后再说
我们当然可以把审核的步骤写在同一个方法里,但这样的话,这个方法承担的责任就很大了,任何步骤修改、增加都必须修改此方法,不符合单一职责原则和开闭原则。
并且,有个更灵活的地方是,请求可以通过任意一个对象传入,比如上面的请假和加薪,员工完全可以直接向最大的boss请求,也就是这样写:
boss.doCheck(request_1);
不过注意的是,在链的末端之前必须要正确处理请求