设计模式之策略模式

一、定义

策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

二、角色

这个模式涉及到三个角色:

  • 环境(Context)角色:持有一个Strategy的引用。
  • 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
  • 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

三、策略模式结构图

四、策略模式的利弊

策略模式的优点

(1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。

(2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。

策略模式的缺点

(1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
  (2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。

五、策略模式的例子

使用场景

假设现在要设计一个贩卖各类书籍的电子商务网站的购物车系统。一个最简单的情况就是把所有货品的单价乘上数量,但是实际情况肯定比这要复杂。比如,本网站可能对所有的高级会员提供每本20%的促销折扣;对中级会员提供每本10%的促销折扣;对初级会员没有折扣。

根据描述,折扣是根据以下的几个算法中的一个进行的:

算法一:对初级会员没有折扣。

算法二:对中级会员提供10%的促销折扣。

算法三:对高级会员提供20%的促销折扣。

代码

  • 抽象的策略接口MemberStrategy,提供计算价格的方法

public interface MemberStrategy {

    public double calcPrice(double bookPrice);
}
  • 具体策略角色一,初级会员PrimaryStrategy,没有优惠
public class PrimaryStrategy implements MemberStrategy {
    @Override
    public double calcPrice(double bookPrice) {
        return bookPrice;
    }
}
  • 具体策略角色二,中级会员IntermediateStrategy,提供9折优惠
public class IntermediateStrategy implements MemberStrategy {
    @Override
    public double calcPrice(double bookPrice) {
        return 0.9*bookPrice;
    }
}
  • 具体策略角色三,高级会员AdvancedStrategy,提供8折优惠
public class AdvancedStrategy implements MemberStrategy {
    @Override
    public double calcPrice(double bookPrice) {
        return 0.8*bookPrice;
    }
}
  • 环境角色,Price,持有具体策略角色的应用,且调用了具体策略的方法。
public class Price {

    private MemberStrategy strategy;

    public Price(MemberStrategy strategy) {
        this.strategy = strategy;
    }


    public double quote(double price) {
        return strategy.calcPrice(price);
    }
}
  • 测试
public class StrategyTest {


    public static void main(String[] args) {


        PrimaryStrategy primaryStrategy = new PrimaryStrategy();
        IntermediateStrategy intermediateStrategy = new IntermediateStrategy();
        AdvancedStrategy advancedStrategy = new AdvancedStrategy();


        Price primaryPrice = new Price(primaryStrategy);
        Price intermediatePrice = new Price(intermediateStrategy);
        Price advancePrice = new Price(advancedStrategy);
        System.out.println("初级会员价格: "+primaryPrice.quote(200));
        System.out.println("中级会员价格: "+intermediatePrice.quote(200));
        System.out.println("高级会员价格: "+advancePrice.quote(200));

    }
}
---------------------------------------------
初级会员价格: 200.0
中级会员价格: 180.0
高级会员价格: 160.0
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容