题目:
企业发放的奖金根据利润提成。利润低于或等于10万时,奖金可提10%;利润高于10万元,低于20万元时,低于10万的部分按10%提成,高于10万元的部分可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万的部分,可提成3%;60万到100万之间时,高于60万的部分,可提成1.5%,高于100万时,超过100万的部分按1%提成,从键盘输入当月利润,求应发放奖金总数?要求采用责任链模式来设计
金额用 BigDecimal 防止误差
代码实现:
1.抽象责任
package com.fund.fundmodel.interview.handler;
import com.fund.fundmodel.interview.request.ChainRequest;
import java.math.BigDecimal;
public abstract class ChainHandler {
private ChainHandler next;
public abstract void execute(ChainRequest request);
public ChainHandler getNext() {
return next;
}
public ChainHandler setNext(ChainHandler next) {
this.next = next;
return this.next;
}
/**
* 链条的处理方法,单向链表的遍历。
*/
public void ProcessRequest(ChainHandler command, ChainRequest request) {
if (command == null) {
throw new IllegalArgumentException("请先使用setCommand方法去注册命令");
}
command.execute(request);
// 递归处理下一级链条
if (command.getNext() != null) {
ProcessRequest(command.getNext(),request);
}
}
}
参数类
@Data
public class ChainRequest {
BigDecimal p;
BigDecimal x;
}
2.具体责任
1).10万以内的利润直接计算后输出,超过10万的,仅计算10万内的奖金
public class P1Service extends ChainHandler {
@Override
public void execute(ChainRequest request) {
if((request.getX().compareTo(BigDecimal.valueOf(0))==1 && request.getX().compareTo(BigDecimal.valueOf(100000))==-1)||(request.getX().compareTo(BigDecimal.valueOf(100000))==0)){
request.setP(request.getX().multiply(BigDecimal.valueOf(0.1)));
System.out.println("输出总奖金数额:"+request.getP());
}
else if((request.getX().compareTo(BigDecimal.valueOf(100000))==1)){
request.setP(BigDecimal.valueOf(100000).multiply(BigDecimal.valueOf(0.1)));
}
}
}
2).20万内的利润直接计算后输出,超过20万的,仅计算10万至20万这部分金额(总计10万元)的奖金
public class P2Service extends ChainHandler {
@Override
public void execute(ChainRequest request) {
if((request.getX().compareTo(BigDecimal.valueOf(100000))==1 && request.getX().compareTo(BigDecimal.valueOf(200000))==-1)||(request.getX().compareTo(BigDecimal.valueOf(200000))==0)){
request.setP(request.getP().add(request.getX().subtract(BigDecimal.valueOf(100000)).multiply(BigDecimal.valueOf(0.075))));
System.out.println("输出总奖金数额:"+request.getP());
}
else if((request.getX().compareTo(BigDecimal.valueOf(200000))==1)){
request.setP(request.getP().add(BigDecimal.valueOf(100000).multiply(BigDecimal.valueOf(0.075))));
}
}
}
3)..40万内的利润直接计算后输出,超过40万的,仅计算20万至40万这部分金额(总计20万元)的奖金
public class P4Service extends ChainHandler {
@Override
public void execute(ChainRequest request) {
if((request.getX().compareTo(BigDecimal.valueOf(200000))==1 && request.getX().compareTo(BigDecimal.valueOf(400000))==-1)||(request.getX().compareTo(BigDecimal.valueOf(400000))==0)){
request.setP(request.getP().add(request.getX().subtract(BigDecimal.valueOf(200000)).multiply(BigDecimal.valueOf(0.05))));
System.out.println("输出总奖金数额:"+request.getP());
}
else if((request.getX().compareTo(BigDecimal.valueOf(400000))==1)){
request.setP(request.getP().add(BigDecimal.valueOf(200000).multiply(BigDecimal.valueOf(0.05))));
}
}
}
4).60万内的利润直接计算后输出,超过60万的,仅计算40万至60万这部分金额(总计20万元)的奖金
public class P6Service extends ChainHandler {
@Override
public void execute(ChainRequest request) {
if((request.getX().compareTo(BigDecimal.valueOf(400000))==1 && request.getX().compareTo(BigDecimal.valueOf(600000))==-1)||(request.getX().compareTo(BigDecimal.valueOf(600000))==0)){
request.setP(request.getP().add(request.getX().subtract(BigDecimal.valueOf(400000)).multiply(BigDecimal.valueOf(0.03))));
System.out.println("输出总奖金数额:"+request.getP());
}
else if((request.getX().compareTo(BigDecimal.valueOf(600000))==1)){
request.setP(request.getP().add(BigDecimal.valueOf(200000).multiply(BigDecimal.valueOf(0.03))));
}
}
}
5).100万内的利润直接计算后输出,超过100万的,计算60万至100万这部分金额(总计40万元)的奖金加上超出100万部分的奖金后输出。
public class P10Service extends ChainHandler {
@Override
public void execute(ChainRequest request) {
if((request.getX().compareTo(BigDecimal.valueOf(600000))==1 && request.getX().compareTo(BigDecimal.valueOf(1000000))==-1)||(request.getX().compareTo(BigDecimal.valueOf(1000000))==0)){
request.setP(request.getP().add(request.getX().subtract(BigDecimal.valueOf(600000)).multiply(BigDecimal.valueOf(0.015))));
System.out.println("输出总奖金数额:"+request.getP());
}
else if((request.getX().compareTo(BigDecimal.valueOf(1000000))==1)){
request.setP(request.getP().add(BigDecimal.valueOf(400000).multiply(BigDecimal.valueOf(0.015))).add(request.getX().subtract(BigDecimal.valueOf(1000000)).multiply(BigDecimal.valueOf(0.01))));
System.out.println("输出总奖金数额:"+request.getP());
}
}
}
3.抽象链条
public abstract class WorkFlow {
private ChainHandler command;
public WorkFlow() {
this.command = getChainHandler();
}
protected abstract ChainHandler getChainHandler();
/**
* 链条的处理方法,单向链表的遍历。
*/
public void ProcessRequest(ChainRequest request) {
if (command == null) {
throw new IllegalArgumentException("请先使用setCommand方法去注册命令");
}
command.execute(request);
// 递归处理下一级链条
if (command.getNext() != null) {
command = command.getNext();
ProcessRequest(request);
}
}
}
4.具体链条
public class WorkFlow1 extends WorkFlow {
@Override
protected ChainHandler getChainHandler() {
ChainHandler chainHandler = new P1Service();
chainHandler.setNext(new P2Service())
.setNext(new P4Service())
.setNext(new P6Service())
.setNext(new P10Service());
return chainHandler;
}
}
5.主类
public class SuanFa {
public static void main(String[] args){
WorkFlow workFlow = new WorkFlow1();
BigDecimal p=new BigDecimal("0"),x;
System.out.println("请输入利润总额:");
Scanner sc = new Scanner(System.in);
x=sc.nextBigDecimal();
ChainRequest request = new ChainRequest();
request.setP(p);
request.setX(x);
workFlow.ProcessRequest(request);
}
}
补充:
职责链模式(Chain of Responsibility):使多个对象都有机会处理同一个请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
以上责任链的实现时,奖金P,可不通过每个具体责任分别计算,而是判断利润总额是否在该责任类处理范围内,如果在则计算出奖金总额,如果不再则不做处理,交由后面的其他责任类处理。 这种实现方式与职责链模式的定义跟匹配。
6.如果不采用责任链该题解答如下:
public class SuanFa2 {
public static void main(String[] args){
BigDecimal x,p=new BigDecimal("0");
BigDecimal x1,x2,x4,x6,x10;
int n;
System.out.println("请输入利润总额:");
Scanner sc = new Scanner(System.in);
x=sc.nextBigDecimal();
x1=BigDecimal.valueOf(100000).multiply(BigDecimal.valueOf(0.1));//x1=100000*0.1;//总额高于10 000时10 000以下的奖励
x2=x1.add(BigDecimal.valueOf(100000).multiply(BigDecimal.valueOf(0.075)));//x2=x1+100000*0.075;//总额高于20 000时20 000以下的奖励
x4=x2.add(BigDecimal.valueOf(200000).multiply(BigDecimal.valueOf(0.05)));//x4=x2+200000*0.05;//总额高于40 000时40 000以下的奖励
x6=x4.add(BigDecimal.valueOf(200000).multiply(BigDecimal.valueOf(0.03)));//x6=x4+200000*0.03;//总额高于60 000时60 000以下的奖励
x10=x6.add(BigDecimal.valueOf(400000).multiply(BigDecimal.valueOf(0.015)));//x10=x6+400000*0.015;//总额高于1 000 000时1 000 000以下的奖励
n=x.divide(BigDecimal.valueOf(100000)).intValue();
if(n>10){
n=10;
}
switch(n)
{
case 0: p=x.multiply(BigDecimal.valueOf(0.1));break; //p=x*0.1
case 1: p=x1.add(x.subtract(BigDecimal.valueOf(100000)).multiply(BigDecimal.valueOf(0.075)));break;//p=x1+(x-100000)*0.075
case 2:
case 3: p=x2.add(x.subtract(BigDecimal.valueOf(200000)).multiply(BigDecimal.valueOf(0.05)));break; //p=x2+(x-200000)*0.05;
case 4:
case 5: p=x4.add(x.subtract(BigDecimal.valueOf(400000)).multiply(BigDecimal.valueOf(0.03)));break;//p=x4+(x-400000)*0.03
case 6:
case 7:
case 8:
case 9: p=x6.add(x.subtract(BigDecimal.valueOf(600000)).multiply(BigDecimal.valueOf(0.015)));break;// p=x6+(x-600000)*0.015
case 10: p=x10.add(x.subtract(BigDecimal.valueOf(1000000)).multiply(BigDecimal.valueOf(0.01)));break;//p=x10+(x-1000000)*0.01
}
System.out.println("输出总奖金数额:"+p);
}
}