设计模式篇(六)—— 策略模式

1.策略模式基本介绍

​ 在软件开发中常常遇到这种情况,实现某一个功能有多种算法或者策略,我们可以根据应用场景的不同选择不同的算法或者策略来完成该功能。把一个类(A)中经常改变或者将来可能改变的部分提取出来,作为一个接口(B),然后在类(A)中包含这个接口(B),这样类(A)的实例在运行时就可以随意调用实现了这个接口的类(C)的行为。比如定义一系列的算法,把每一个算法封装起来, 并且使它们可相互替换,使得算法可独立于使用它的客户而变化。这就是策略模式。

策略模式涉及三种角色:

1.环境(Context)角色:持有一个Strategy,策略模式运行的环境。

2.抽象策略(Strategy)角色:抽象角色,通常为一个接口或者抽象类实现。此角色给出所有的具体策略类所需的接口。根据不同的需求,产生不同的策略或算法的接口。

3.具体策略(ConcreteStrategy)角色:具体实现策略类,包装了相关的算法或行为。

​ 优点:1、可以动态的改变对象的行为   

缺点:1、客户端必须知道所有的策略类,并自行决定使用哪一个策略类     

2、策略模式将造成产生很多策略类

 

2.策略模式代码实现

抽象策略类

/**
 * @author Merlin
 * @Title: DiscountStrategy
 * @ProjectName designpattern
 * @Description: 抽象策略类(抽象打折类)
 * @date 2018/8/1510:54
 */
public interface DiscountStrategy {
​
    /**
     * 计算衣服的价格
     * @param clothesPrice 衣服的原价
     * @return  计算出打折后的价格
     */
    double discount(double clothesPrice);
}

具体策略

/**
 * @author Merlin
 * @Title: PrimaryMemberStrategy
 * @ProjectName designpattern
 * @Description: 初级会员打折类
 * @date 2018/8/1511:18
 */
public class PrimaryMemberStrategy implements DiscountStrategy {
​
    @Override
    public double discount(double clothesPrice) {
        System.out.println("初级会员没有折扣!");
        return clothesPrice;
    }
}
/**
 * @author Merlin
 * @Title: IntermediateMemberStrategy
 * @ProjectName designpattern
 * @Description: 中级会员打折类
 * @date 2018/8/1511:20
 */
public class IntermediateMemberStrategy implements DiscountStrategy {
​
​
    @Override
    public double discount(double clothesPrice) {
        System.out.println("中级会员打九折!");
        return clothesPrice * 0.9;
    }
}
/**
 * @author Merlin
 * @Title: AdvancedMemberStrategy
 * @ProjectName designpattern
 * @Description: 高级会员打折类
 * @date 2018/8/1511:21
 */
public class AdvancedMemberStrategy implements DiscountStrategy {
​
    @Override
    public double discount(double clothesPrice) {
        System.out.println("高级会员打八折!");
        return clothesPrice * 0.8;
    }
}

价格类

/**
 * @author Merlin
 * @Title: Clothes
 * @ProjectName designpattern
 * @Description: 价格类
 * @date 2018/8/1511:26
 */
public class Price {
​
    //持有一个策略对象
    private DiscountStrategy discountStrategy;
​
    /**
     * 构造函数,传入一个具体的策略对象
     * @param discountStrategy : 具体的策略对象
     */
    public Price(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }
​
​
    /**
     * 计算衣服的价格
     * @param clothesPrice 衣服的原价
     * @return 计算出打折后的价格
     */
    public double quote(double clothesPrice){
        return this.discountStrategy.discount(clothesPrice);
    }
}

客户端

/**
 * @author Merlin
 * @Title: Client
 * @ProjectName designpattern
 * @Description: 客户端
 * @date 2018/8/1513:20
 */
public class Client {
​
    public static void main(String[] args){
        //选择并创建需要使用的策略对象
        DiscountStrategy discountStrategy = new IntermediateMemberStrategy();
​
        //创建环境
        Price price = new Price(discountStrategy);
​
        //计算价格
        double quote = price.quote(300);
        System.out.println("衣服打折后的价格为:" + quote);
    }
​
}

测试结果

中级会员打九折!
衣服打折后的价格为:270.0

 

总结

策略模式的重心

  策略模式的重心不是如何实现算法,而是如何组织、调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。

  算法的平等性

  策略模式一个很大的特点就是各个策略算法的平等性。对于一系列具体的策略算法,大家的地位是完全一样的,正因为这个平等性,才能实现算法之间可以相互替换。所有的策略算法在实现上也是相互独立的,相互之间是没有依赖的。

  所以可以这样描述这一系列策略算法:策略算法是相同行为的不同实现。

  运行时策略的唯一性

  运行期间,策略模式在每一个时刻只能使用一个具体的策略实现对象,虽然可以动态地在不同的策略实现中切换,但是同时只能使用一个。

  公有的行为

  经常见到的是,所有的具体策略类都有一些公有的行为。这时候,就应当把这些公有的行为放到共同的抽象策略角色Strategy类里面。当然这时候抽象策略角色必须要用Java抽象类实现,而不能使用接口。

  这其实也是典型的将代码向继承等级结构的上方集中的标准做法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值