美文网首页
设计模式-策略模式

设计模式-策略模式

作者: 奔向学霸的路上 | 来源:发表于2020-03-27 20:29 被阅读0次

策略模式

策略模式定义了一系列的算法,并将每一个算法封装起来,使每个算法可以相互替代,使算法本身和使用算法的客户端分割开来,相互独立。

我们假设一种创景,商品打折活动,针对新客户9折,针对老客户8.8折,针对VIP客户5折,下面我们来用策略模式实现一下。
类图

图片.png

代码实现

/**
 * 策略模式-价格
 */
public interface PriceStrategy {
    /**
     * 获取价格
     * @param originalPrice 原始价格
     * @return 不同客户优惠后的价格
     */
    BigDecimal getPrice(BigDecimal originalPrice);
}
/**
 * 新客策略类
 */
public class NewCustomerStrategy implements PriceStrategy{
    @Override
    public BigDecimal getPrice(BigDecimal originalPrice) {
        System.out.println("新客9折");
        return originalPrice.multiply(new BigDecimal(0.9).setScale(2, BigDecimal.ROUND_HALF_UP));
    }
}
/**
 * 老客策略类
 */
public class OldCustomerStrategy implements PriceStrategy{
    @Override
    public BigDecimal getPrice(BigDecimal originalPrice) {
        System.out.println("老客8折");
        return originalPrice.multiply(new BigDecimal(0.8).setScale(2, BigDecimal.ROUND_HALF_UP));
    }
}
/**
 * vip策略类
 */
public class VipCustomerStrategy implements PriceStrategy {

    @Override
    public BigDecimal getPrice(BigDecimal originalPrice) {
        System.out.println("vip5折");
        return originalPrice.multiply(new BigDecimal(0.5).setScale(2, BigDecimal.ROUND_HALF_UP));
    }
}
/**
 * 报价上下文
 */
public class QuoteContext {
    /**
     * 持有报价策略
     */
    private PriceStrategy strategy;

    /**
     * 注入报价策略
     * @param strategy
     */
    public QuoteContext(PriceStrategy strategy) {
        this.strategy = strategy;
    }

    /**
     * 回调具体的报价策略方法
     * @param originalPrice 原始价格
     * @return
     */
    public BigDecimal contextMethod(BigDecimal originalPrice){
        return strategy.getPrice(originalPrice);
    }
}
public class PriceStrategyTest {
    public static void main(String[] args) {
        //创建新客报价策略
        PriceStrategy priceStrategy = new NewCustomerStrategy();
        //创建报价上下文,并设置具体的报价策略
        QuoteContext context = new QuoteContext(priceStrategy);
        //调用报价上下文的方法
        BigDecimal price = context.contextMethod(new BigDecimal(100));
        System.out.println("新客的到手价格:"+ price);
    }
}

上述例子中,我们首先创建了一个价格策略接口PriceStrategy,其次我们定义了三种客群(其实对应三个实际策略类),QuoteContext实际上是使用了某种策略的类。

策略模式的结构

策略接口PriceStrategy:策略接口,用来约束一系列策略算法
具体的策略实现NewCustomerStrategy、OldCustomerStrategy 、VipCustomerStrategy:具体的策略实现,也就是具体的策略算法
策略上下文QuoteContext:策略上下文,负责和具体的策略实现交互

策略模式的作用

就是把具体的算法实现从业务逻辑中剥离出来,成为一系列独立算法类,使得它们可以相互替换。

策略模式的着重点

策略模式就是把各个平等的具体实现进行抽象、封装成为独立的算法类,然后通过上下文和具体的算法类来进行交互。各个策略算法都是平等的,地位是一样的,正是由于各个算法的平等性,所以它们才是可以相互替换的。虽然我们可以动态的切换各个策略,但是同一时刻只能使用一个策略。

策略模式的本质:

分离算法,选择实现。
  如果你仔细思考策略模式的结构和功能的话,就会发现:如果没有上下文,策略模式就回到了最基本的接口和实现了,只要是面向接口编程,就能够享受到面向接口编程带来的好处,通过一个统一的策略接口来封装和分离各个具体的策略实现,无需关系具体的策略实现。
  貌似没有上下文什么事,但是如果没有上下文的话,客户端就必须直接和具体的策略实现进行交互了,尤其是需要提供一些公共功能或者是存储一些状态的时候,会大大增加客户端使用的难度;引入上下文之后,这部分工作可以由上下文来完成,客户端只需要和上下文进行交互就可以了。这样可以让策略模式更具有整体性,客户端也更加的简单。
  策略模式体现了开闭原则:策略模式把一系列的可变算法进行封装,从而定义了良好的程序结构,在出现新的算法的时候,可以很容易的将新的算法实现加入到已有的系统中,而已有的实现不需要修改。
  策略模式体现了里氏替换原则:策略模式是一个扁平的结构,各个策略实现都是兄弟关系,实现了同一个接口或者继承了同一个抽象类。这样只要使用策略的客户端保持面向抽象编程,就可以动态的切换不同的策略实现以进行替换。
参考:https://blog.csdn.net/tugangkai/article/details/88074288

相关文章

网友评论

      本文标题:设计模式-策略模式

      本文链接:https://www.haomeiwen.com/subject/fwjruhtx.html