策略模式

轻便更换策略

  • 概念
  • 类图
  • 代码实例

概念

当不同时间段,业务上会采取不同的策略,这个可以采用策略模式,将一种抽象计算方式通过一个Context类暴露给Client,然后在Context中会根据条件选择具体的算法实现策略。一种方式是通过客户端决定具体的算法策略通过Context()构造方法传入,还有一种方式通过简单工厂方式,传入一个type创建具体算法策略由Context决定,第二种方式更大降低了与客户端的的耦合性

好处:可以轻松的替换和增加具体算法策略,不会影响客户端,降低了耦合性。

类图

在这里插入图片描述

Strategy:抽象策略接口

ConcreteStrategy:具体的一种策略

Context:上下文类,暴露给客户端,里面包含Strategy

Client:客户端类,通过Context来使用一种具体策略完成对应的逻辑

代码实例

场景:
设计一个店员计费器,可以输入商品的单价和数量,最终获取总额,其中可能会有活动,商品打折情况,满多少减多少情况等各种策略(算法),为了替换算法时不会影响客户端,采用策略模式。

CashSuper接口(Strategy)

/**
 * @author duanyimiao
 * @create 2018-09-11 6:09 PM
 * @description 定义一个抽象的收费抽象类
 **/
public abstract class CashSuper {
    /**
     *
     * @param money 原始金额
     * @return 优惠后的金额
     */
    public abstract double acceptCash(double money);
}

CashNormal具体策略类(ConcreteStrategy1)

/**
 * @author duanyimiao
 * @create 2018-09-11 6:12 PM
 * @description 正常计费
 **/
public class CashNormal extends CashSuper{
    @Override
    public double acceptCash(double money) {
        return money;
    }
}

CashRebate具体策略类(ConcreteStrategy2)

/**
 * @author duanyimiao
 * @create 2018-09-11 6:12 PM
 * @description 折扣
 **/
public class CashRebate extends CashSuper {
    private double moneyRebate = 1;

    public CashRebate() {

    }

    public CashRebate(String rebate) {
        this.moneyRebate = Double.parseDouble(rebate);
    }

    @Override
    public double acceptCash(double money) {
        return money*moneyRebate;
    }
}

CashReturn具体策略类(ConcreteStrategy3)

/**
 * @author duanyimiao
 * @create 2018-09-11 6:12 PM
 * @description 满多少减多少
 **/
public class CashReturn extends CashSuper {
    private double moneyCondition;
    private double moneyReturn;

    public CashReturn() {

    }

    public CashReturn(String moneyCondition, String moneyReturn) {
        this.moneyCondition = Double.parseDouble(moneyCondition);
        this.moneyReturn = Double.parseDouble(moneyReturn);
    }

    @Override
    public double acceptCash(double money) {
        return money - (Math.floor(money/moneyCondition)*moneyReturn);
    }
}

CashContext(Context)策略上下文

 * @author duanyimiao
 * @create 2018-09-11 6:35 PM
 * @description CashContext中的getMoney()方法暴露给client端
 *
 * 策略模式和简单工厂模式结合
 **/
public class CashContext {
    private CashSuper cashSuper;

    public CashContext() {

    }

    public CashContext(String discountWay) {
        switch (discountWay) {
            case "five-discount":
                cashSuper = new CashRebate("0.5");
                break;
            case "eight-discount":
                cashSuper = new CashRebate("0.8");
                break;
            case "util 50 return 1":
                cashSuper = new CashReturn("50", "1");
                break;
            default:
                cashSuper = null;
        }
    }
    //此方法暴露给Client,避免将CashSuper类以及其方法暴露到客户端,客户端只需要Context类就行,关于其内部的具体实现逻辑无需care
    public double getMoney(double money){
        return cashSuper.acceptCash(money);
    }

}

Client 客户端类

/**
 * @author duanyimiao
 * @create 2018-09-11 6:36 PM
 * @description
 **/
public class Client {
    public static void main(String[] args) {
        /**
         * 客户端只知道CashContext,通过传入type,最终获取到计算后结果,无须关注具体这些计算的方式
         */
        CashContext cashContext1 = new CashContext("eight-discount");
        double money1 = 100*1;
        double total1 = cashContext1.getMoney(money1);
        double money2 = 50*3;
        CashContext cashContext2 = new CashContext("util 50 return 1");
        double total2 = cashContext2.getMoney(money2);
        System.out.println("total "+(total1+total2));
    }
}

输出结果:

total 227.0
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值