• 策略模式


    就自己实际产品中用的的模式进行分析:

     策略模式

           本系统中的还款模块涉及到多种还款方式的算法,并且后期可能需要经常性的调整或增减算法,因此本系统采用策略模式来定义这一系列的算法,把它们一个个封装起来,并且使它们可相互替换。使得算法可独立于使用它的客户而变化。

           策略模式的结构示意图:

     

    图4-1 策略模式结构图

    (1) RepaymentModeI:
            策略接口,用来约束一系列具体的策略算法。Context使用这个接口来调用具体的策略实现定义的算法。

    public interface RepaymentModeI {
    
        /**
    
         * 获得应还利息
    
         *@param annualRate 年利率
    
         *@param loanAount 借款金额
    
         *@param deadline 借款期限
    
         *@param num 还款月数
    
         *@return Double 利息
    
         * */
    
        public Double interest(double annualRate, double loanAount, int deadline, int num);
    
        /**
    
         * 获得应还本金
    
         *@param annualRate 年利率
    
         *@param loanAount 借款金额
    
         *@param deadline 借款期限
    
         *@param num 还款月数
    
         *@return Double 本金
    
         * */
    
        public Double principal(double annualRate, double loanAount, int deadline, int num);
    
        /**
    
         * 获得应还本息
    
         *@param annualRate 年利率
    
         *@param loanAount 借款金额
    
         *@param deadline 借款期限
    
         *@return Double 本息
    
         * */
    
        public Double interAndPri(double annualRate, double loanAount, int deadline, int num);
    
        /**
    
         * 计算利率
    
         * @param annualRate 年利率
    
         * @return 利率
    
         * */
    
        public double rate(double annualRate);
    
    }

    (2) RepaymentModeBy____:
            具体的策略实现,也就是具体的算法实现。目前系统对应有:按天到期还款,按月到期还款(是指每月还息,到期还本的借款方式),按月分期还款(分期还款采用的是通用的"等额本息还款法"),按季分期付款(采用每月付息,按季等额还本的计算方式),实现代码以按月分期还款的计算本金方法为例:

    /**
    
         * 按月分期还款:分期还款采用的是通用的"等额本息还款法",即借款人每月以相等的金额偿还贷款本息。也是银行房贷等采用的方法。
    
         * 这里要注意区分 等额本息还款法和等额本金还款法
    
         * @author sl
    
         * */
    
        public Double interAndPri(double annualRate, double loanAount, int deadline, int num) {
    
           /**
    
            * 等额本息还款公式推导 设贷款总额为A,银行月利率为β,总期数为m(个月),月还款额设为X,
    
            * 则各个月所欠银行贷款为:
    
            * 第一个月A(1+β)-X
    
            * 第二个月[A(1+β)-X](1+β)-X = A(1+β)^2-X[1+(1+β)]
    
            * 第三个月{[A(1+β)-X](1+β)-X}(1+β)-X = A(1+β)^3-X[1+(1+β)+(1+β)^2]
    
            *  …
    
            * 由此可得第n个月后所欠银行贷款为:
    
            * A(1+β)^n-X[1+(1+β)+(1+β)^2+…+(1+β)^(n-1)] = A(1+β)^n-X[(1+β)^n-1]/β
    
            * 由于还款总期数为m,也即第m月刚好还完银行所有贷款,因此有:
    
            * A(1+β)^m-X[(1+β)^m-1]/β = 0
    
            * 由此求得:
    
             * X = Aβ(1+β)^m/[(1+β)^m-1]
    
            * */
    
           Return loanAount*rate(annualRate)*Math.pow((1+rate(annualRate)), deadline)/(Math.pow((1+rate(annualRate)), deadline)-1);
    
    }


    (3) Context:

        上下文,负责和具体的策略类交互,通常上下文会持有一个真正的策略实现,上下文还可以让具体的策略类来获取上下文的数据,甚至让具体的策略类来回调上下文的方法。

    public class Context {
    
        private RepaymentModeI repaymentModeI;
    
        private Double annualRate;                 //年利率
    
        private Double loanAount;                  //借款金额
    
        private int deadline;                      //截止期限(按月计算)
    
        private int num;                           //月数
    
        /**
    
         * 构造方法,传入一个具体的策略对象
    
         * @param repaymentMode 具体的策略对象
    
         */
    
        public Context(RepaymentModeI repaymentMode, Double annualRate,
    
            Double loanAount,int deadline, int num) {
    
           this.repaymentModeI = repaymentMode;
    
           this.annualRate = annualRate;
    
           this.loanAount = loanAount;
    
           this.deadline = deadline;
    
           this.num = num;
    
        }
    
        /**
    
         * 上下文对客户端提供的操作接口,可以有参数和返回值
    
         */
    
        public Double getInterest() {                        //获得利息
    
           //通常会转调具体的策略对象进行算法运算
    
        return repaymentModeI.interest(annualRate, loanAount, deadline, num);
    
        }
    
    }

    策略模式的本质:分离算法,选择实现。
      仔细思考策略模式的结构和实现的功能,会发现,如果没有上下文,策略模式就回到了最基本的接口和实现了,只要是面向接口编程的,那么就能够享受到接口的封装隔离带来的好处。也就是通过一个统一的策略接口来封装和隔离具体的策略算法,面向接口编程的话,自然不需要关心具体的策略实现,也可以通过使用不同的实现类来实例化接口,从而实现切换具体的策略。
      看起来好像没有上下文什么事情,但是如果没有上下文,那么就需要客户端来直接与具体的策略交互,尤其是当需要提供一些公共功能,或者是相关状态存储的时候,会大大增加客户端使用的难度。因此,引入上下文还是很必要的,有了上下文,这些工作就由上下文来完成了,客户端只需要与上下文交互就可以了,这样会让整个设计模式更独立、更有整体性,也让客户端更简单。
      但纵观整个策略模式实现的功能和设计,它的本质还是“分离算法,选择实现”,因为分离并封装了算法,才能够很容易的修改和添加算法;也能很容易的动态切换使用不同的算法,也就是动态选择一个算法来实现需要的功能了。

  • 相关阅读:
    node.js的querystring模块
    jsonp的作用
    js开发性能(一)
    express创建第一个web应用
    安装express
    关于【歧视】的一点事
    在统计报表中用到的sql语法记录
    北京民航总医院杀医事件
    那些自杀的人似乎更有勇气
    河南人究竟偷了多少井盖?
  • 原文地址:https://www.cnblogs.com/shenliang123/p/3835454.html
Copyright © 2020-2023  润新知