设计模式-策略模式

发布时间:2024年01月17日

设计模式-策略模式

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,并将每个算法封装在具有共同接口的独立类中,使得它们可以在运行时互换使用。这种模式提供了对算法家族进行分装,可以按需动态地改变对象的行为。

抽象提取理论:

  1. 行为抽象
  2. 策略对象的具体化
  3. 上下文中的抽象使用
  4. 策略的选择与切换

代码需求:模拟商场收银软件,营业员根据客户购买商品的单价和数量,打折(例如7折,6折)会变化,满减(200-100,300-150)会变化,原价其中之一进行收费。你会如何利用面向对象原则来设计这个demo呢?

策略模式实现

代码结构图

在这里插入图片描述

  1. 抽象行为:CashSuper
  2. 策略对象具体化:CashNormal(无优惠),CashRebate(打折优惠),CashReturn(满减优惠)
  3. 上下文切换:CashContext

代码实现:

/**
 *  策略抽象类
 */
public abstract class CashSuper {
    /**
     * 算法方法
     * @Param 单价
     * @Param 数量
     */
    abstract double acceptCash(double price,int number);
}
/**
 * 正常算法
 */
public class CashNormal extends CashSuper{
    @Override
    double acceptCash(double price, int number) {
        return price * number;
    }
}
/**
 * 打折优惠
 */
public class CashRebate extends CashSuper{
    /**
     * 默认打折折扣率
     */
    private double moneyRebate = 1d;

    /**
     * 设置打折折扣率
     */
    public CashRebate(double moneyRebate) {
        this.moneyRebate = moneyRebate;
    }

    /**
     * 实现打折方法
     * @param price 单价
     * @param number 数量
     */
    @Override
    double acceptCash(double price, int number) {
        return price * number * moneyRebate;
    }
}
/**
 * 满减算法
 */
public class CashReturn extends CashSuper{

    /**
     * 返利条件
     */
    private double nmoneyConditionn = 0d;

    /**
     * 返利值
     */
    private double nmoneyReturn = 0d;

    /**
     * 指定返利条件和返利值
     * @param nmoneyConditionn 返利条件
     * @param nmoneyReturn 返利值
     */
    public CashReturn(double nmoneyConditionn, double nmoneyReturn) {
        this.nmoneyConditionn = nmoneyConditionn;
        this.nmoneyReturn = nmoneyReturn;
    }

    /**
     * 实现打折方法
     * @param price 单价
     * @param number 数量
     */
    @Override
    double acceptCash(double price, int number) {
        double sum = price * number;
        if (nmoneyConditionn> 0 && sum>= nmoneyConditionn){
            // Math.floor:向下取整。计算满足多次返利条件情况(根据实际业务)
            sum = sum - Math.floor(sum / nmoneyConditionn) * nmoneyReturn;
        }
        return sum;
    }
}
/**
 * 获取上下文类
 */
public class CashContext {
    private CashSuper cashSuper;

    /**
     * 初始化时,定义策略
     */
    public CashContext(CashSuper cashSuper){
        this.cashSuper = cashSuper;
    }

    /**
     * 上下文接口
     */
    public double getResult(double num1,int num2){
        // 根据策略,调用策略接口
        return cashSuper.acceptCash(num1, num2);
    }
}
/**
 * 客户端
 */
public class StrategyDemo {
    public static void main(String[] args) {
        // 没有打折优惠
        CashContext cashContext = new CashContext(new CashNormal());
        System.out.println("无打折优惠:" + cashContext.getResult(200, 1));

        // 打7折
        CashContext cashContext2 = new CashContext(new CashRebate(0.7d));
        System.out.println("打7折优惠:" + cashContext2.getResult(200, 1));

        // 满减优惠 满200 优惠100
        CashContext cashContext3 = new CashContext(new CashReturn(200,100));
        System.out.println("打7折优惠:" + cashContext3.getResult(200, 1));

    }
}

输出结果:

无打折优惠:200.0
打7折优惠:140.0
打7折优惠:100.0

在此我们实现了两种优惠方法,通过构造函数的方式可以动态指定打折力度或满减条件。

优化

但是……会出现以下问题

  1. 客户端与上下文过于依赖:每次计算产品的时候 都需要输入指定的参数。
  2. 耦合度高:创建上下文对象,需要创建两个对象。

利用简单工厂模式进行优化:

/**
 * 获取上下文类
 */
public class CashContext {
    private CashSuper cashSuper;

    /**
     * 初始化时,定义策略
     */
    public CashContext(CashSuper cashSuper){
        this.cashSuper = cashSuper;
    }

    /**
     * 上下文接口
     */
    public double getResult(double num1,int num2){
        // 根据策略,调用策略接口
        return cashSuper.acceptCash(num1, num2);
    }

    /**
   	* 利用简单工厂模式进行优化
   	* 缺点,这样修改规则或新增规则时 需要给更改switch里面的内容,违背了开闭原则.貌似可以利用反射来再进行一步优化
   	*/
    public CashContext (String way){
        switch (way){
            case "normal":
                cashSuper = new CashNormal();
                break;
            case "rebate":
                cashSuper = new CashRebate(0.7);
                break;
            case "return":
                cashSuper = new CashReturn(200, 100);
                break;
            default:
                cashSuper = new CashNormal();
                break;
        }
    }
}
/**
 * 客户端
 */
public class StrategyDemo {
    public static void main(String[] args) {
        // 没有打折优惠
        CashContext cashContext = new CashContext(new CashNormal());
        System.out.println("无打折优惠:" + cashContext.getResult(200, 1));

        // 打7折
        CashContext cashContext2 = new CashContext(new CashRebate(0.7d));
        System.out.println("打7折优惠:" + cashContext2.getResult(200, 1));

        // 满减优惠 满200 优惠100
        CashContext cashContext3 = new CashContext(new CashReturn(200,100));
        System.out.println("打7折优惠:" + cashContext3.getResult(200, 1));

        // 优化使用 ->> 打7折
        CashContext cashContext4 = new CashContext("rebate");
        System.out.println("打7折优惠:" + cashContext4.getResult(200, 1));
    }
}

100));
System.out.println(“打7折优惠:” + cashContext3.getResult(200, 1));

    // 优化使用 ->> 打7折
    CashContext cashContext4 = new CashContext("rebate");
    System.out.println("打7折优惠:" + cashContext4.getResult(200, 1));
}

}


文章来源:https://blog.csdn.net/m0_62649352/article/details/135650491
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。