策略模式

作者: Jackson杰 | 来源:发表于2019-06-18 13:57 被阅读7次

一 定义

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。
策略模式让算法独立于使用它的客户而独立变化。

二 模式结构

角色介绍:

  • Context:上下文环境,起承上启下的作用,屏蔽高层模块对策略、算法的直接访,封装可能存在的变化。
  • Strategy:抽象的策略,通常为接口,定义每个策略或者算法必须具有的属性和方法。
  • ConcreteStrategyA,ConcreteStrategyB:具体的策略,实现抽象策略中的操作。

三 实例

我们以显示生活中,到商场买东西为例,商场一般会根据不同的客户定制不同的报价策略,比如新用户不打折,消费1000元以上打九折,老用户打9折,消费900元以上打八折,VIP用户打八折,消费800元以上打七折。当然,如果不采用策略模式,可以全部用if-else对不同的客户进行判断,这样的话会造成程序臃肿,可读性和扩展性都会变差,所以我们采用策略模式。代码如下:

  • 抽象的策略接口
    定义每个策略必须实现的方法,这里是根据客户的消费金额计算打折后的金额。
public interface IDiscountStrategy {

    /**
     * 根据消费金额,计算实际花费金额
     * @param count
     * @return
     */
    double getPrice(double count);
}
  • 具体的策略
    分别实现新客户、老客户、VIP客户的策略,实现抽象策略里定义的方法。
public class NewCustomerStrategy implements IDiscountStrategy {

    @Override
    public double getPrice(double count) {
        System.out.println("-----新用户报价策略----");
        if (count < 1000) {
            return count;
        } else {
            return count * 0.9;
        }

    }
}
public class OldCustomerStrategy implements IDiscountStrategy{

    @Override
    public double getPrice(double count) {
        System.out.println("-----老用户报价策略----");
        if (count < 900) {
            return count*0.9;
        } else {
            return count * 0.8;
        }
    }
}
public class VipCustomerStrategy implements IDiscountStrategy{

    @Override
    public double getPrice(double count) {
        System.out.println("-----VIP用户报价策略----");
        if (count < 800) {
            return count*0.8;
        } else {
            return count * 0.7;
        }
    }
}
  • Context角色
public class StrategyContext {

    // 持有一个策略实现的引用
    private IDiscountStrategy mIDiscountStrategy;

    public StrategyContext(IDiscountStrategy strategy) {
        this.mIDiscountStrategy = strategy;
    }

    public double offerPrice(double count){
        return mIDiscountStrategy.getPrice(count);
    }


}
  • 测试代码
// 新客户
        IDiscountStrategy newDiscountStrategy=new NewCustomerStrategy();
        StrategyContext newStrategyContext=new StrategyContext(newDiscountStrategy);
        System.out.println("您消费的金额是:"+ newStrategyContext.offerPrice(1000));

        // 老客户
        IDiscountStrategy oldDiscountStrategy=new OldCustomerStrategy();
        StrategyContext oldStrategyContext =new StrategyContext(oldDiscountStrategy);
        System.out.println("您消费的金额是:"+ oldStrategyContext.offerPrice(900));

        // vip客户
        IDiscountStrategy vipDiscountStrategy=new VipCustomerStrategy();
        StrategyContext vipStrategyContext =new StrategyContext(vipDiscountStrategy);
        System.out.println("您消费的金额是:"+ vipStrategyContext.offerPrice(800));

通过上例,我们可以看到,通过建立抽象的策略,然后将不同的策略构建成一个具体的策略实现,通过不同的策略实现算法替换,程序的可读性,扩展性都比较好。

四 优缺点

优点:

  • 算法可以自由切换
  • 结构清晰,使用简单直观,避免使用多重条件判断
  • 耦合度相对较低,扩展方便
  • 操作封装更彻底,数据更安全

缺点:

  • 随着策略的增加,子类也会变得繁多。

使用场景:

  • 多个子类只有在算法或者行为上 不同的场景
  • 算法需要自由切换的场景

相关文章

网友评论

    本文标题:策略模式

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