设计模式(四)—— 责任链模式

设计模式(四)—— 责任链模式,第1张

1 简介

责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者的链,请求在这条链上传递,直到链上的某个接收者处理此请求,或者每个对象都可以处理请求,并传给“下家”,直到最终链上每个对象都处理完。

responsibility [rɪˌspɑːnsəˈbɪləti] 责任,负责 pattern [ˈpætərn] 模式,方式;

这种模式可以避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求。

Java中,异常机制就是一种责任链模式。一个try语句可以对应多个catch,如果第一个catch不匹配,就自动跳到第二个catch

2 案例1

(链表方式定义职责链)请假条审批流程,我们可以在请假处理流程中,增加新的“副总经理”角色,审批大于等于10天,小于20天的请假。审批流程变为:
① 如果请假天数小于3天,主任审批;
② 如果请假天数大于等于3天,小于10天,经理审批;
③ 大于等于10天,小于20天的请假,副总经理审批;
④ 如果大于等于20天,小于30天,总经理审批;
⑤ 如果大于等于30天,提示拒绝;

该过程的实现大致有以下几个步骤:

步骤一:封装请假的基本信息
public class Vacation {
    private String employee;
    private int duration;
    private String reason;

    public Vacation(String employee, int duration, String reason) {
        this.employee = employee;
        this.duration = duration;
        this.reason = reason;
    }

    public String getEmployee() {
        return employee;
    }
    public void setEmployee(String employee) {
        this.employee = employee;
    }
    public int getDuration() {
        return duration;
    }
    public void setDuration(int duration) {
        this.duration = duration;
    }
    public String getReason() {
        return reason;
    }
    public void setReason(String reason) {
        this.reason = reason;
    }
}
步骤二:定义抽象处理者(Leader
public abstract class Leader {
    protected String name;
    protected Leader nextLeader;

    public Leader(String name) {
        this.name = name;
    }

    public void setNextLeader(Leader nextLeader) {
        this.nextLeader = nextLeader;
    }

    public abstract void handleVacation(Vacation vacation);
}
第三步:定义具体处理者

主任:

public class Director extends Leader {

    public Director(String name) {
        super(name);
    }

    @Override
    public void handleVacation(Vacation vacation) {
        if (vacation.getDuration() < 3) {
            System.out.println("员工:" + vacation.getEmployee() + ",请假天数:" + vacation.getDuration());
            System.out.println("主任:" + this.name + ",审批通过!");
        } else {
            if (this.nextLeader != null) {
                this.nextLeader.handleVacation(vacation);
            }
        }
    }
}

经理:

public class Manager extends Leader {

    public Manager(String name) {
        super(name);
    }

    @Override
    public void handleVacation(Vacation vacation) {
        if (vacation.getDuration() < 10) {
            System.out.println("员工:" + vacation.getEmployee() + ",请假天数:" + vacation.getDuration());
            System.out.println("经理:" + this.name + ",审批通过!");
        } else {
            if (this.nextLeader != null) {
                this.nextLeader.handleVacation(vacation);
            }
        }
    }
}

副总经理:

public class ViceGeneralManager extends Leader {

    public ViceGeneralManager(String name) {
        super(name);
    }

    @Override
    public void handleVacation(Vacation vacation) {
        if (vacation.getDuration() < 20) {
            System.out.println("员工:" + vacation.getEmployee() + ",请假天数:" + vacation.getDuration());
            System.out.println("副总经理:" + this.name + ",审批通过!");
        } else {
            if (this.nextLeader != null) {
                this.nextLeader.handleVacation(vacation);
            }
        }
    }
}

总经理:

public class GeneralManager extends Leader {

    public GeneralManager(String name) {
        super(name);
    }

    @Override
    public void handleVacation(Vacation vacation) {
        if (vacation.getDuration() < 30) {
            System.out.println("员工:" + vacation.getEmployee() + ",请假天数:" + vacation.getDuration());
            System.out.println("总经理:" + this.name + ",审批通过!");
        } else {
            if (this.nextLeader != null) {
                this.nextLeader.handleVacation(vacation);
            }
        }
    }
}

第四步:测试

class Client {
    public static void main(String[] args) {
        Leader director = new Director("段誉");
        Leader manager = new Manager("鸠摩智");
        Leader viceGeneralManager = new ViceGeneralManager("萧峰");
        Leader generalManager = new GeneralManager("扫递僧");

        director.setNextLeader(manager);
        manager.setNextLeader(viceGeneralManager);
        viceGeneralManager.setNextLeader(generalManager);

        Vacation vacation = new Vacation("慕容复", 28, "回姑苏");
        director.handleVacation(vacation);
        System.out.println("审批流程:" + director.name + "-->" + manager.name + "-->" + viceGeneralManager.name + "-->" + generalManager.name);
    }
}

// 员工:慕容复,请假天数:28
// 总经理:扫递僧,审批通过!
// 审批流程:段誉-->鸠摩智-->萧峰-->扫递僧
3 案例2

创建抽象类AbstractLogger,带有详细的日志记录级别。然后创建三种类型的记录器,都扩展了AbstractLogger。每个记录器消息的级别是否属于自己的级别,如果是则相应地打印出来,否则将不打印并把消息传给下一个记录器。

步骤一:创建抽象的记录器类
public abstract class AbstractLogger {
    public static int INFO = 1;
    public static int DEBUG = 2;
    public static int ERROR = 3;

    protected int level;

    protected AbstractLogger nextLogger;

    public void setNextLogger(AbstractLogger nextLogger) {
        this.nextLogger = nextLogger;
    }

    public void logMessage(int level, String message) {
        if (this.level < level) {
            write(message);
        }
        if (nextLogger != null) {
            nextLogger.logMessage(level, message);
        }
    }

    abstract protected void write(String message);
}
步骤二:创建扩展了该记录器类的实体类

ConsoleLogger

public class ConsoleLogger extends AbstractLogger {

    public ConsoleLogger(int level) {
        this.level = level;
    }

    @Override
    protected void write(String message) {
        System.out.println("Standard Console::Logger: " + message);
    }
}

ErrorLogger

public class ErrorLogger extends AbstractLogger {

    public ErrorLogger(int level) {
        this.level = level;
    }

    @Override
    protected void write(String message) {
        System.out.println("Error Console::Logger:" + message);
    }
}

FileLogger

public class FileLogger extends AbstractLogger {

    public FileLogger(int level) {
        this.level = level;
    }

    @Override
    protected void write(String message) {
        System.out.println("File Console::Logger: " + message);
    }
}
第三步:测试

创建不同类型的记录器,赋予它们不同的错误级别,并在每个记录器中设置下一个记录器。每个记录器中的下一个记录器代表的是链的一部分:

public class ChainPatternDemo {
    private static AbstractLogger getChainOfLoggers() {
        AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
        AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
        AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);

        consoleLogger.setNextLogger(errorLogger);
        errorLogger.setNextLogger(fileLogger);
        return consoleLogger;
    }

    public static void main(String[] args) {
        AbstractLogger loggerChain = getChainOfLoggers();
        loggerChain.logMessage(AbstractLogger.INFO, "This is an information");
        loggerChain.logMessage(AbstractLogger.DEBUG, "This is a debug level information");
        loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information");
    }
}

// Standard Console::Logger: This is a debug level information
// Standard Console::Logger: This is an error information
//File Console::Logger: This is an error information
参考

https://zhuanlan.zhihu.com/p/368932005
https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/786911.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存