策略模式简述

什么是策略模式?

主要在“策略”两个字,当我们在做一件事有多种方法(做这件事只能用一个方法)。比方我们要去旅行,可以选择汽车、火车、飞机、自驾,我们会选择其中一种而不是多种结合。更恰当的例子,比方客户买了东西下单,我们负责计算应付金额。对于普通用户、会员、高级会员,他们的优惠方式是不同的,而且通常情况下都只能享用一种优惠。

使用的场景

①多个类只区别在表现行为不同,可以使用Strategy模式,在运行时动态选择具体要执行的行为。
②需要在不同情况下使用不同的策略(算法),或者策略还可能在未来用其它方式来实现。
③对客户隐藏具体策略(算法)的实现细节,彼此完全独立

举例子

下面以计算付款金额为例子,对策略模式进行说明。

抽象策略角色

根据普通用户、会员、高级会员对应的三种策略,抽象出一个接口
接口方法是计算实收金额,入参是应收金额。

/**
 * 描述:将计算金额的策略抽象出一个接口
 * <p>作者: aliyu
 * <p>创建时间: 2021-10-14 5:13 下午
 */
public interface CountAmountStrategy {

    /**
     * 计算实收金额
     * @param basicNum 应收金额
     * @return
     */
    public BigDecimal countAmount(BigDecimal basicNum);
}

具体策略

普通用户:

/**
 * 描述:普通用户策略
 * <p>作者: aliyu
 * <p>创建时间: 2021-10-14 5:29 下午
 */
public class NormalStrategy implements CountAmountStrategy{

    @Override
    public BigDecimal countAmount(BigDecimal basicNum) {
        //这里写普通用户的具体策略
        return null;
    }
}

会员策略:

/**
 * 描述:会员策略
 * <p>作者: aliyu
 * <p>创建时间: 2021-10-14 5:29 下午
 */
public class VipStrategy implements CountAmountStrategy{

    @Override
    public BigDecimal countAmount(BigDecimal basicNum) {
        //这里写会员的具体策略
        return null;
    }
}

高级会员策略:


/**
 * 描述:高级会员策略
 * <p>作者: aliyu
 * <p>创建时间: 2021-10-14 5:29 下午
 */
public class SuperVipStrategy implements CountAmountStrategy{

    @Override
    public BigDecimal countAmount(BigDecimal basicNum) {
        //这里写高级会员的具体策略
        return null;
    }
}

上下文环境角色

包含对一个具体策略对象实例的引用,供客户端应用程序调用
客户端调用的时候,需要通过一个上下文环境,而不是直接调用。

/**
 * 描述:策略执行上下文
 * <p>作者: aliyu
 * <p>创建时间: 2021-10-14 5:45 下午
 */
public class Content {
    /**
     * 包含对一个具体策略对象实例的引用
     */
    private Strategy strategy;

    public Content(Strategy strategy) {
        this.strategy = strategy;
    }

    /**
     * 计算实收金额
     * @param basicNum 商品标价
     * @return
     */
    public BigDecimal countAmount(BigDecimal basicNum){
        return strategy.countAmount(basicNum);
    }

    /**
     * 模拟客户端调用
     * @param args
     */
    public static void main(String[] args) {
        Content content = new Content(new NormalStrategy());
        //Content content = new Content(new VipStrategy());
        //Content content = new Content(new SuperVipStrategy());

    }
}

好处是

避免暴露复杂的,与算法相关的内部数据结构;算法独立于使用它的客户应用。
利于维护和扩展。
可以在客户端程序运行时动态的指定需要的策略,进行算法运算,而不需要修改客户端应用程序内容。如果照下面的写法,就不需要修改客户端代码(应用了反射):

 Class c=Class.forName("com.aliyu.learn.strategy"+前端传过来策略的类名);
 Content content = new Content((Strategy) c.newInstance());

每一种策略都使用一个类实现,有效的防止因修改一个策略而对其他策略造成影响(代码都在不同的类文件,自然不会影响)
增加一个策略如果不使用的话,自然对原有的程序不会影响,但如果要使用的,还得加代码。
修改一个策略,一般不需要修改客户端应用程序内容(如果要加入参数的话除外)。

坏处是

会产生很多的策略类。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值