策略模式 与 上下文context的作用

用户多种会员的价格优惠不一样,正常的代码实现 if

    public static BigDecimal calPrice(BigDecimal orderPrice,String buyerType){
        if("svip".equals(buyerType)){

            if(orderPrice.compareTo(BigDecimal.valueOf(28))>0){
                return orderPrice.multiply(BigDecimal.valueOf(0.8));
            }
        }

        if("vip".equals(buyerType)){
            return orderPrice.multiply(BigDecimal.valueOf(0.9));
        }

        if("ssvip".equals(buyerType)){
            return orderPrice.multiply(BigDecimal.valueOf(0.7));
        }

        return orderPrice;
    }

客户端调用

 public static void main(String[] args) {
        calPrice(BigDecimal.valueOf(200),"svip");

 }

这样的话,如果新增一种会员,则 calPrice 方法就得做调整,违背了开闭原则,而且逻辑结构与算法过于耦合。

接下来就是策略模式出场了,先看下定义,策略模式:指的是定义一系列算法,将每一个算法封装起来,并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化。
1、定义计算价格的接口,具体实现方法由具体的策略类来定义

public interface Buyer {
    /**
     * 计算价格
     * @param orderPrice
     * @return
     */
    BigDecimal calPrice(BigDecimal orderPrice);

}

2、具体的策略类

public class SSvipBuyer implements Buyer {
    @Override
    public BigDecimal calPrice(BigDecimal orderPrice) {
        return orderPrice.multiply(BigDecimal.valueOf(0.7));
    }
}

public class SvipBuyer implements Buyer {
    @Override
    public BigDecimal calPrice(BigDecimal orderPrice) {
        return orderPrice.multiply(BigDecimal.valueOf(0.8));
    }
}

public class VipBuyer implements Buyer {
    @Override
    public BigDecimal calPrice(BigDecimal orderPrice) {
        return orderPrice.multiply(BigDecimal.valueOf(0.9));
    }
}

3、上下文类(就是集成算法的类)

public class Cashiler {

    private Buyer buyer;
    public Cashiler(Buyer buyer){
        this.buyer = buyer;
    }

    public BigDecimal quota(BigDecimal orderPrice){
        return buyer.calPrice(orderPrice);
    }
}

4、客户端调用

public class SimpleCalPrice {

    public static void main(String[] args) {
      
        //不使用上下文调用
        Buyer buyer = new SSvipBuyer();
        BigDecimal price = buyer.calPrice(BigDecimal.valueOf(100));
        System.out.println(price);
        
        //使用上下文调用
        Cashiler cashiler = new Cashiler(new SvipBuyer());
        BigDecimal quota = cashiler.quota(BigDecimal.valueOf(100));
        System.out.println(quota);

    }

到这里,可能大家就有疑问了,这边用上下文调用和直接调用策略接口的方式好像没什么不同,那么这个上下文有什么作用呢?
试想一下,如果每个具体的策略都有一个需要执行的代码,例如 System.out.println("每个策略类都需要执行的代码"),这样你需要再每个策略类添加这个代码,
如果有上下文这个类,你可以把公用的代码写在该类中

public class Cashiler {

    private Buyer buyer;
    public Cashiler(Buyer buyer){
        this.buyer = buyer;
    }

    public BigDecimal quota(BigDecimal orderPrice){
        System.out.println("每个策略类都需要执行的代码");
        return buyer.calPrice(orderPrice);
    }
}

在实际开发中,我们的需求往往不会像结构示意图那样,如此简单、如此simple。实际较为常见的情况就是:上层的调用需要与接口之间有一定的交互。交互的可能是一些属性,或是一些方法。这样的交互往往会让接口变的难以调用;于是上下文的引入就是势在必行。将相关的属性或一些公共的方法封装到上下文中,让上下文去和接口进行复杂的交互。而上层的调用只需要跟上下文打交道就可以。

策略模式仅仅封装算法,提供新的算法插入到已有系统中,策略模式并不决定在何时使用何种算法。在什么情况下使用什么算法是由客户端决定的。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值