策略模式
(Strategy)
说穿了就是通过对接口的定义,将应用中变化的部分独立出来由子类实现,从而实现松耦合。
问题的起源来自银监会项目的需求变化,“本次应缴金额”的计算公式有变动。公式计算规则如下:
二、“本次应缴金额”自动运算公式
收缴系统的[收入收缴管理]-[监管收费]-[应缴信息录入]中“本次应缴金额”的自动计算公式需改为:
(一)每年第1期“本次应缴金额”
机构监管费=(上年末实收资本×机构监管费率×风险调整系数)÷2
业务监管费=[(上年末资产总额-实收资本)×业务监管费率×风险调整系数-境外分支机构在所在国家缴纳的监管费]÷2
(二)每年第2期“本次应缴金额”
机构监管费=全年应缴机构监管费-第1次应缴机构监管费=上年末实收资本×机构监管费率×风险调整系数-第1次应缴机构监管费
业务监管费=全年应缴业务监管费-第1次应缴业务监管费=[(上年末资产总额-实收资本)×业务监管费率×风险调整系数-境外分支机构在所在国家缴纳的监管费]-第1次应缴业务监管费
请你公司协助完成收缴系统的修改和调试工作。
|
拿到需求时单是看到琳琅满目的数据字段我就已经头晕了。。,再看看手中原有的代码,计算公式全是在actionPerform()
一个方法内完成的,我如果在原有基础上修改,势必会使用大量
if else
,绕啊绕,换个人也会头晕。“只在此山中,云深不知处”的意境虽然美,但是不适用在代码中。
于是我想到了策略模式。
通过观察,公式需要计算
1. 每年需要计算两期:第一期和第二期(废话:P);
2. 每期需要计算两种不同的费用:机构监管费和业务监管费;
于是我定义出接口:
public
interface
ICountStrategy {
/**
*
计算机构监管费
*/
public
UFDouble countCorpfee();
/**
*
计算业务监管费
*/
public
UFDouble countBusifee();
}
|
public
class
CalStrategyObject {
private
UFDouble
receivedfund
=
null
;
//
上年末实收资本
private
UFDouble
totalfund
=
null
;
//
上年末总资产
private
UFDouble
riskvalue
=
null
;
//
风险调整系数
private
UFDouble
corprate
=
null
;
//
机构监管费率
private
UFDouble
busirate
=
null
;
//
业务监管费率
private
UFDouble
outerfund
=
null
;
//
境外分支机构在所在国家缴纳的监管费
private
UFDouble
corpfund1
=
null
;
//
第
1
次应缴机构监管费
private
UFDouble
busifund1
=
null
;
//
第一次应缴业务监管费
//setter getter
方法
}
|
为了节省篇幅,
Setter Getter
方法我就不写了。通过这个类,其他程序员就知道,原来参与计算的就是这些数据啊!
public
abstract
class
AbstractCountStrategy
implements
ICountStrategy {
private
boolean
isRefresh
=
false
;
protected
CalStrategyObject
calobj
=
null
;
/**
*
@param
calobj
用于计算的数据
vo
*/
public
AbstractCountStrategy(CalStrategyObject calobj) {
this
.
calobj
= calobj;
}
public
void
setCalStrategyObj(CalStrategyObject calobj) {
this
.
calobj
= calobj;
}
}
|
下一步,开始真正实现每期不同费用的算法了。
/**
*
第一期的计算公式
*
*
@author
wuz
*
*/
public
class
FirstTermCalculator
extends
AbstractCountStrategy {
public
FirstTermCalculator(CalStrategyObject calobj) {
super
(calobj);
}
/*
*
业务监管费
=[(
上年末资产总额
-
实收资本
)¡Á
业务监管费率
¡Á
风险调整系数
-
境外分支机构在所在国家缴纳的监管费
]¡Â2;
*/
public
UFDouble countBusifee() {
UFDouble totalBusifee = CalculatorUtil.countTotalBusiFee(
calobj
);
return
totalBusifee.div(2);
}
/*
*
每年第
1
期
“
本次应缴金额
”
机构监管费
=(
上年末实收资本
¡Á
机构监管费率
¡Á
风险调整系数
)¡Â2
*/
public
UFDouble countCorpfee() {
UFDouble totalFee = CalculatorUtil.countTotalCorpFee(
calobj
);
return
totalFee.div(2);
}
}
|
public
class
SecondTermCalculator
extends
AbstractCountStrategy {
public
SecondTermCalculator(CalStrategyObject calobj) {
super
(calobj);
}
/*
*
业务监管费
=
全年应缴业务监管费
-
第
1
次应缴业务监管费
=[(
上年末资产总额
-
实收资本
)¡Á
业务监管费率
¡Á
风险调整系数
-
境外分支机构在所在国家缴纳的监管费
]-
第
1
次应缴业务监管费
*/
public
UFDouble countBusifee() {
UFDouble busifee1 =
calobj
.getBusifund1();
//
第
1
次应缴业务监管费
UFDouble totalfee = CalculatorUtil.countTotalBusiFee(
calobj
);
//
全年应缴业务监管费
return
totalfee.sub(busifee1);
}
/*
*
机构监管费
=
全年应缴机构监管费
-
第
1
次应缴机构监管费
=
上年末实收资本
¡Á
机构监管费率
¡Á
风险调整系数
-
第
1
次应缴机构监管费
*/
public
UFDouble countCorpfee() {
UFDouble corpfee = CalculatorUtil.countTotalCorpFee(
calobj
);
UFDouble orgfee1 =
calobj
.getCorpfund1();
//
第
1
次应缴机构监管费
return
corpfee.sub(orgfee1);
}
}
|
这里由于公式中,“
(上年末实收资本×机构监管费率×风险调整系数)”和“(上年末资产总额-实收资本)×业务监管费率×风险调整系数-境外分支机构在所在国家缴纳的监管费 ”两个公式多次用到,我将其提炼到一个工具类
CalculatorUtil
中:
public
class
CalculatorUtil {
/**
*
计算总的机构监管费
上年末实收资本
¡Á
机构监管费率
¡Á
风险调整系数
*
*
@param
calobj
*
@return
*/
public
static
UFDouble countTotalCorpFee(CalStrategyObject calobj) {
UFDouble receivedFund = calobj.getReceivedfund();
UFDouble riskvalue = calobj.getRiskvalue();
UFDouble rate = calobj.getCorprate();
return
receivedFund.multiply(rate).multiply(riskvalue);
}
/**
*
业务监管费总额
(
上年末资产总额
-
实收资本
)¡Á
业务监管费率
¡Á
风险调整系数
-
境外分支机构在所在国家缴纳的监管费
*
业务监管费率是一个范围值,不同范围取值不一样
*
*
*
@param
calobj
*
@return
*
@throws
Exception
*/
public
static
UFDouble countTotalBusiFee(CalStrategyObject calobj){
UFDouble total = calobj.getTotalfund();
//
上年末资产总额
UFDouble receivedFund = calobj.getReceivedfund();
//
实收资本
UFDouble sub = total.sub(receivedFund);
//
按照
(
上年末资产总额
-
实收资本
)
计算业务监管费
UFDouble business = BusiRateUtil.getInstance().getBusiFee(sub);
UFDouble riskrate = calobj.getRiskvalue();
//
风险调整系数
UFDouble outfee = calobj.getOuterfund();
//
境外分支机构在所在国家缴纳的监管费
return
business.multiply(riskrate).sub(outfee);
}
}
|
public
class
CalculatorFactory {
/**
*
@param
type
期次
*
@return
*/
public
ICountStrategy createCalculator(
int
type){
if
(type ==1 ){
return
new
FirstTermCalculator();
}
else
{
return
new
SecondTermCalculator();
}
return
null
;
}
}
|
public
class
PayableCalculator {
...
private
void
onCount1()
throws
Exception {
CalStrategyObject obj = getCalobj();
ICountStrategy counter =
new
FirstTermCalculator(obj);
UFDouble orgFee = counter.countCorpfee();
data
.setOrgfee(orgFee);
UFDouble busifee = counter.countBusifee();
data
.setBusifee(busifee);
}
...
private
void
onCount2()
|