zoukankan      html  css  js  c++  java
  • 设计模式 | 职责链模式(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);
        }
    }

    结果输出:

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

    总结:

    这个模式算是一个结构比较简单的,也很好理解,只不过之前自己想的时候完全没有想出来可以用这样的方式来实现。
    又能把请求传递下去又能让处理者之间,以及处理者和客户端之间解耦,真的很巧妙。
    不过像上面说的,继任者是由客户端决定的,但实际上具体处理者之间有潜在的逻辑关系,如果客户端没有正确的设置链条可能会导致请求得不到处理。
    比如上面的例子,直接拿洗好的鸭子去包装显然是包装不了的。
    所以需要把文档写得足够清晰,以供客户端正确使用。
  • 相关阅读:
    C# 类 根据属性名称取属性值
    WebService WCF 契约的解释
    NHibenate xml 数据库配置 说明
    使Spring.NET的IOC容器支持动态加载的程序集
    知识点滴:持久层,DAO,API,DAL,BLL,DLL,csproj,sln
    spring.net nhibernate 分布布式事务(下)
    简明教程 C# Webservice实例
    C# 中 以 &# 打头的 编码 是: html 编码解码地址 转换
    spring.net 结合简单三层实例
    关于行号输出的简单命令
  • 原文地址:https://www.cnblogs.com/imoqian/p/13907502.html
Copyright © 2011-2022 走看看