目录
笔者经常遇到 需要 比较区间的问题,比如:
20< x <= 40 , -无穷 到 正无穷, 20<=x
遇到这种,如果 单纯写if else if else if else 估计人都写傻了
所以我们用 抽象的思维 搞一下这个 问题,
多年使用 设计模式我的感悟就是:
使用设计模式,不仅仅显得逼格高,最重要的是 你可以很清晰的看到代码背后的业务逻辑,不仅让别人更快的运维,而且自己去扩展的时候可很快的去找到对应的方法和类去修改,不用 再代码块中一步一步的找寻!
抽象
这个需求就是 根据 最终值,判断属于哪一个区间,区间是变化的,所以我们把区间抽象出来,判断的 变化的,所以我们也抽象出来
接口 是一系列的方法的抽象,还无法形成 抽象类
所以很自然的就是先 把 方法 抽象出来成 接口
public interface Section {
boolean getResultBySection(Double finishValue);
}
然后就是抽象类 拥有公共处理方法,同时具体的 比较方法 其实 是 子类各不相同的,所以我们需要 在抽象类中使用 接口适配器的有点,定义一个抽象方法,让每个子类去实现
public abstract class SectionAb implements Section {
protected boolean endFlag;
protected boolean starFlag;
protected Double starScore;//当有开闭符号,但是 没有给定值,那么 默认就给一个0 ,或者 无穷大
protected Double endScore;
protected String endSectionSybol;
protected String starSectionSybol;
//1.模板方法,设置参数
public final void prepare(boolean endFlag, boolean starFlag, Double starScore,
Double endScore, String endSectionSybol, String starSectionSybol) {
this.endFlag = endFlag;
this.starFlag = starFlag;
this.starScore = starScore;
this.endScore = endScore;
this.endSectionSybol = endSectionSybol;
this.starSectionSybol = starSectionSybol;
}
@Override
public boolean getResultBySection(Double finishValue) {
return getResult(finishValue);
}
public abstract boolean getResult(Double finishValue);
}
具体的实现类
我们 把 所有的 区间 归纳一下 就是 双区间,单区间(前无,后无),无区间 ,
于是我们简单写一个 实现类
public class SectionAbSingleEnd extends SectionAb {
@Override
public boolean getResult(Double finishValue) {
boolean flag = false;
if (endSectionSybol.equals("<")) {
if (finishValue.compareTo(endScore) == -1) {
flag = true;
}
} else {
if (finishValue.compareTo(endScore) == 0
|| finishValue.compareTo(endScore) == -1) {
flag = true;
}
}
return flag;
}
}
怎么去使用这个 实现类,我们想到可以用 普通工厂类,抽象工厂,静态工厂,
明显 我们可以穷举,那么就直接 最简单的普通工厂
public class SectionFactory {
public static SectionAb createSection(String sybolend, String sybolStart, Double startValue, Double endValue) {
boolean endFlag = getBooleanBystr(sybolend);
boolean starFlag = getBooleanBystr(sybolStart);
SectionAb result = null;
if (endFlag && !starFlag) {
result = new SectionAbSingleEnd();
}
}
具体的使用
首先是 根据 条件 ,将具体的 实现类 构造出来,根据 里氏代换原则(Liskov Substitution Principle)可以用父类的地方,肯定可以用子类,调用抽象类中的方法
SectionAb sectionAb = SectionFactory.createSection(ruleModel.getEarlyMaxAmountSybol(), ruleModel.getEarlyMinAmountSybol(),
ruleModel.getEarlyMinAmount(), ruleModel.getEarlyMaxAmount());
boolean earlyFlag = sectionAb.getResultBySection(sourceModel.getCreditLimit());
return earlyFlag;
附记
在 判断出区间之后,我们肯定常常会遇到 计算
1—5 的区间 x*100+0.9
5—-10区间 x*0.9
这里我们分享一个 el表达式的算法
引入谷歌的包:
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>3.3.0</version>
</dependency>
String scoreRule = "riskRate*(period*amount-plandisValue)";
// 编译表达式
Expression compiledExp = AviatorEvaluator.compile(scoreRule);
Map<String, Object> env = new HashMap<String, Object>();
env.put("riskRate", Double.valueOf(riskRate));
env.put("amount", Double.valueOf(amount));
env.put("period", Integer.valueOf(period));
env.put("plandisValue", plandisValue);
BigDecimal scoreActual = new BigDecimal((compiledExp.execute(env).toString()));