设计模式-责任链模式

遇到一个面试的场景题目,让实现税率的计算

请使用Java语言实现如下税率计算:

1~5000 税率 0

5001~8000 3%

8001~17000 10%

17001~30000 20%

30001~40000 25%

40001~60000 30%

60001~85000 35%

85001~ 45%

要求

ⅰ. 逻辑正确,代码优雅

ⅱ. 可扩展性,考虑区间的变化,比如说起征点从5000变成10000等等,或者说85000以上的征税50%。

ⅲ. 推荐使用合适的设计模式

这里举个例子,比如说税前10000元,5000部分是不扣税,后面5000,3000扣税3%,2000扣税10%。

�这里考虑使用责任链的模式实现

这里先实现了一个基本的Handler(其实也可以不用,因为这里实际上只给了一个实现handler),当有多个的时候需要一个共同的父类

java 复制代码
package com.zhs.demoutil.chain;

import lombok.Data;

@Data
public abstract class BasePriceHandler{

    private BasePriceHandler nextHandler;

    public void setHandler(BasePriceHandler handler) {
        this.nextHandler = handler;
    }
    // 计算价格,这里交给子类实现
    protected abstract double calculatePrice(double amount);
    // 计算下一个,如果有下一个的话
    protected double calculatePriceNext(double quantity) {
        if (nextHandler != null) {
            return nextHandler.calculatePrice(quantity);
        } else {
            return 0.0;
        }
    }
}

这里是具体的实现的一个段的一个率的计算方式

java 复制代码
package com.zhs.demoutil.chain;

class TieredPricingHandler extends BasePriceHandler {
    // 数额
    private final double start;
    // 顶部金额,也就是在这区间进行计算税
    private final double end;
    // 对应税率
    private final double tierPrice;



    public TieredPricingHandler(double start,double end, double tierPrice) {
        this.start = start;
        this.end = end;
        this.tierPrice = tierPrice;
    }

	// 具体的计算
    public double calculatePrice(double amount) {
        // 只有大于这个start的时候才需要用到这个handler,不然就可以直接算0
        if (amount > start) {
            double totalPrice = Math.min((amount-start),end-start) * tierPrice/100;
            double remainingPrice = calculatePriceNext(amount);
            return totalPrice + remainingPrice;
        }
        return 0;
    }
}

增加一个链的类,用来组对应的链结构

java 复制代码
package com.zhs.demoutil.chain;

class PricingHandlerChain {
    private BasePriceHandler headHandler;

    public void addHandler(BasePriceHandler handler) {
        if (headHandler == null) {
            headHandler = handler;
        } else {
            BasePriceHandler currentHandler = headHandler;
            while (currentHandler.getNextHandler() != null) {
                currentHandler = currentHandler.getNextHandler();
            }
            currentHandler.setNextHandler(handler);
        }
    }

    public double calculatePrice(int quantity) {
        if (headHandler != null) {
            return headHandler.calculatePrice(quantity);
        } else {
            return 0.0;
        }
    }
}

测试的执行类

java 复制代码
package com.zhs.demoutil.chain;

public class Main {
    public static void main(String[] args) {
        PricingHandlerChain pricingHandlerChain = new PricingHandlerChain();
    	// 这里就是直接创建对应的handler然后加入到链里面
        pricingHandlerChain.addHandler(new TieredPricingHandler(0,5000, 0));
        pricingHandlerChain.addHandler(new TieredPricingHandler(5000,8000, 3));
        pricingHandlerChain.addHandler(new TieredPricingHandler(8000,17000, 10));
        pricingHandlerChain.addHandler(new TieredPricingHandler(17000,30000, 20));
        pricingHandlerChain.addHandler(new TieredPricingHandler(30000,40000, 25));
        pricingHandlerChain.addHandler(new TieredPricingHandler(40000,60000, 30));
        pricingHandlerChain.addHandler(new TieredPricingHandler(60000,85000, 35));
        pricingHandlerChain.addHandler(new TieredPricingHandler(85000,Integer.MAX_VALUE, 45));

        int quantity = 10000;
        double price = pricingHandlerChain.calculatePrice(quantity);
        System.out.println("数量:" + quantity);
        System.out.println("费用:" + price);
    }
}

这里就是责任链模式的实现了税率的计算,只要是责任链,基本套路就是一样的,可以定一个基类,然后子类就去继承,然后实现对应的处理逻辑,可以在父类里面直接调用下一个,然后子类里面实现当前符合的计算逻辑,最后加一个Chain类进行组链,调用链的计算方法就可以了

相关推荐
守护者1706 分钟前
JAVA学习-练习试用Java实现“使用Arrays.toString方法将数组转换为字符串并打印出来”
java·学习
源码哥_博纳软云8 分钟前
JAVA同城服务场馆门店预约系统支持H5小程序APP源码
java·开发语言·微信小程序·小程序·微信公众平台
禾高网络10 分钟前
租赁小程序成品|租赁系统搭建核心功能
java·人工智能·小程序
学会沉淀。16 分钟前
Docker学习
java·开发语言·学习
如若12317 分钟前
对文件内的文件名生成目录,方便查阅
java·前端·python
初晴~1 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
黑胡子大叔的小屋2 小时前
基于springboot的海洋知识服务平台的设计与实现
java·spring boot·毕业设计
ThisIsClark2 小时前
【后端面试总结】深入解析进程和线程的区别
java·jvm·面试
雷神乐乐2 小时前
Spring学习(一)——Sping-XML
java·学习·spring
小林coding3 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云