怎么解决区间比较的问题(工厂模式)

目录

笔者经常遇到 需要 比较区间的问题,比如:
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()));

猜你喜欢

转载自blog.csdn.net/sinat_27639721/article/details/81062270