23种设计模式(8)—— 责任链模式

责任链模式

一、概念

是一个请求有多个对象来处理,这些对象是一条链,但具体由哪个对象来处理,根据条件判断来确定,如果不能处理会传递给该链中的下一个对象,直到有对象处理它为止。

二、使用场景

  • 有多个对象可以处理同一个请求,具体哪个对象处理该请求待运行时刻再确定。
  • 在不明确指定接受者的情况下,向多个对象中的一个提交一个请求。
  • 可动态指定一组对象处理请求,客户端可以动态创建职责链来处理请求。


三、Demo

销售团队处理客户折扣需求

Sales:<=5%
Manager:<=30%
Director:<=40%
Vice President:<=50%
CEO:<=55%
package com.cjian.gof.chain;

/**
 * @Author: cjian
 * @Date: 2022/1/25 15:55
 * @Description:
 */
public abstract class PriceHandler {

    protected PriceHandler nextHander;

    public void setNextHander(PriceHandler nextHander) {
        this.nextHander = nextHander;
    }

    /**
     * 处理折扣请求
     *
     * @param discount
     */
    public abstract void processDiscount(float discount);

    /**
     * 创建PriceHandler的工厂方法
     *
     * @return
     */
    public static PriceHandler createPriceHandler() {
        PriceHandler sales = new Sales();
        PriceHandler manager = new Manager();
        PriceHandler director = new Director();
        PriceHandler vicePresident = new VicePresident();
        PriceHandler ceo = new CEO();

        //设置直接后继
        sales.setNextHander(manager);
        manager.setNextHander(director);
        director.setNextHander(vicePresident);
        vicePresident.setNextHander(ceo);
        return sales;
    }
}
package com.cjian.gof.chain;

/**
 * @Author: cjian
 * @Date: 2022/1/25 15:57
 * @Description: 销售人员,可以批准5%以内的折扣
 */
public class Sales extends PriceHandler {

    @Override
    public void processDiscount(float discount) {
        if (discount <= 0.05) {
            System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), discount);
        } else {//让直接后继来处理
            nextHander.processDiscount(discount);
        }
    }
}
package com.cjian.gof.chain;

/**
 * @Author: cjian
 * @Date: 2022/1/25 15:58
 * @Description: 销售经理,可以批准30%以内的折扣
 */
public class Manager extends PriceHandler {
    @Override
    public void processDiscount(float discount) {
        if (discount <= 0.3) {
            System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), discount);
        } else {//超过直接传递给直接后继
            nextHander.processDiscount(discount);
        }
    }
}
package com.cjian.gof.chain;

/**
 * @Author: cjian
 * @Date: 2022/1/25 15:59
 * @Description: 销售总监,可以批准40%以内的折扣
 */
public class Director extends PriceHandler {
    @Override
    public void processDiscount(float discount) {
        if (discount <= 0.4) {
            System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), discount);
        } else {//超过直接传递给直接后继
            nextHander.processDiscount(discount);
        }
    }
}
package com.cjian.gof.chain;

/**
 * @Author: cjian
 * @Date: 2022/1/25 16:03
 * @Description: 销售副总裁,可以批准50%以内的折扣
 */
public class VicePresident extends PriceHandler {
    @Override
    public void processDiscount(float discount) {
        if (discount <= 0.5) {
            System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), discount);
        } else {//超过直接传递给直接后继
            nextHander.processDiscount(discount);
        }
    }
}
package com.cjian.gof.chain;

/**
 * @Author: cjian
 * @Date: 2022/1/25 16:07
 * @Description: CEO,可以批准55%以内的折扣, 折扣超出55%,拒绝申请
 *
 */
public class CEO extends PriceHandler {
    @Override
    public void processDiscount(float discount) {
        if (discount <= 0.55) {
            System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), discount);
        } else {//让直接后继来处理
            System.out.format("%s拒绝了折扣:%.2f%n", this.getClass().getName(), discount);
        }
    }
}

客户:

package com.cjian.gof.chain;

import java.util.Random;

/**
 * @Author: cjian
 * @Date: 2022/1/25 16:07
 * @Description:
 */
public class Customer {

    private PriceHandler priceHandler;

    public void setPriceHandler(PriceHandler priceHandler) {
        this.priceHandler = priceHandler;
    }

    //只关心折扣请求是否被处理了,不关心被谁处理的。
    public void requestDiscount(float discount) {
        priceHandler.processDiscount(discount);
    }

    public static void main(String[] args) {
        Customer customer = new Customer();
        customer.setPriceHandler(PriceHandler.createPriceHandler());

        Random random = new Random();

        for (int i = 1; i < 5; i++) {
            customer.requestDiscount(random.nextFloat());
        }
    }
}

 四、优缺点

优点:

  • 对象仅需知道该请求会被处理即可,且链中的对象不需要知道链的结构,由客户端负责链的创建,降低了系统的耦合度;
  • 请求处理对象仅需维持一个指向其后继者的引用,而不需要维持它对所有的候选处理者的引用,可简化对象的相互连接;
  • 在给对象分派职责时,职责链可以给我们更多的灵活性,可以在运行时对该链进行动态的增删改,改变处理一个请求的职责;
  • 新增一个新的具体请求处理者时无须修改原有代码,只需要在客户端重新建链即可,符合 “开闭原则”。

缺点:

  • 一个请求可能因职责链没有被正确配置而得不到处理;
  • 可能因为职责链创建不当,造成循环调用,导致系统陷入死循环;
  • 对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,且不方便调试。

本文参考:责任链模式 - 简书

                  什么是责任链模式?_住手丶让我来的博客-CSDN博客_责任链模式

猜你喜欢

转载自blog.csdn.net/cj_eryue/article/details/122687485