设计模式 | 职责链模式(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);
    }
}

结果输出:

清洗员-》清理鸭子~
打包员-》包装鸭子~
不管鸭子在哪个状态,统统传给清理者,他处理不了,会一路传下去,直到正确的人来处理。

总结:

这个模式算是一个结构比较简单的,也很好理解,只不过之前自己想的时候完全没有想出来可以用这样的方式来实现。
又能把请求传递下去又能让处理者之间,以及处理者和客户端之间解耦,真的很巧妙。
不过像上面说的,继任者是由客户端决定的,但实际上具体处理者之间有潜在的逻辑关系,如果客户端没有正确的设置链条可能会导致请求得不到处理。
比如上面的例子,直接拿洗好的鸭子去包装显然是包装不了的。
所以需要把文档写得足够清晰,以供客户端正确使用。

 

posted @ 2020-10-31 22:29  莫愆  阅读(171)  评论(0编辑  收藏  举报