策略模式详解

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

策略模式体现了两个基本的面向对象的设计原则,是面向接口的编程
1.封装变化的概念
2.编程中使用接口,而不是接口的实现

策略模式的组成:
1.抽象策略角色,策略类,通常是一个接口或者抽象类实现 MemberStrategy
2.具体策略角色:包装了相关的算法和行为 PrimaryMemberStrategy IntermediateMemberStrategy
3.环境角色: 持有一个策略类的引用,最终给客户端调用 Price()

策略模式的编写步骤:
1. 对策略对象定义一个公共接口或者抽象类
2. 编写策略类,该类实现了上述定义的接口或者继承了上面的抽象类
3. 在使用策略类的对象中保存一个对策略对象的引用
4. 在使用策略对象的引用中实现构造函数赋值,并可以实现set和get方法实现对策略的改变和获取

策略模式的几个点:
第一:策略模式重点不是如何实现算法,而是如何组织调用这些算法,它相当于搭了一个组织结构,使得程序灵活,更好的维护和扩展
第二:策略模式的各个策略算法都是平等的,对于各个具体的实现策略算法,大家地位一致,因此可以相互替换,相互之间独立,没有依赖
第三: 当程序执行时,拥有策略引用的对象只能使用一个具体的策略方法
第四: 有时候,一些具体的策略实现算法拥有共同的公有的行为,这时候就不能用接口实现了,因为接口的里面只有函数声明,没有具体的实现,只能用抽象类实现,因为抽象类里面不要求所有的方法都是抽象方法。这一点不好理解,我将举例说明。这是典型的将代码向继承等级结构上方集中的标准做法。 此时因为是抽象类,所以采用的是继承,而不是实现接口

public  abstract  class A{
 public  abstract  void a();
 public  void b(){
     System.out.println("我是所有策略算法共有的行为")
 }
}
public class AA extends A{
    public void a(){ 
    }
}
public class AAA extends A{
    public void a(){ 
    }
}

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

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

策略模式的缺点
  (1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
  解决方法采取工厂模式

  (2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。

最后介绍一个快捷键: 在很多时候我们想查询源代码,最后定位查找到interface上去了,可是我们想看的是interface的具体实现,因此我们可以将鼠标点在interface上,按 ctrl + T 可以查看接口的具体实现方法

实例: 购物车中的商品根据会员的等级自动计算价格,
算法一:对初级会员没有折扣。
算法二:对中级会员提供10%的促销折扣。
算法三:对高级会员提供20%的促销折扣。

// 首先定义一个抽象策略角色,策略类接口
public interface MemberStrategy {
    /**
     * 计算图书的价格
     * @param booksPrice    图书的原价
     * @return    计算出打折后的价格
     */
    public double calcPrice(double booksPrice);
}
// 其实实现具体的策略角色,实现了策略的接口,里面是各个算法的具体实现
public class PrimaryMemberStrategy implements MemberStrategy {

    @Override
    public double calcPrice(double booksPrice) {

        System.out.println("对于初级会员的没有折扣");
        return booksPrice;
    }

}

public class IntermediateMemberStrategy implements MemberStrategy {

    @Override
    public double calcPrice(double booksPrice) {

        System.out.println("对于中级会员的折扣为10%");
        return booksPrice * 0.9;
    }

}

public class AdvancedMemberStrategy implements MemberStrategy {

    @Override
    public double calcPrice(double booksPrice) {

        System.out.println("对于高级会员的折扣为20%");
        return booksPrice * 0.8;
    }
}
// 环境角色,价格类
public class Price {
    //持有一个具体的策略对象
    private MemberStrategy strategy;
    /**
     * 构造函数,传入一个具体的策略对象
     * @param strategy    具体的策略对象
     */
    public Price(MemberStrategy strategy){
        this.strategy = strategy;
    }
    // 通过set方法可以修改对象的策略
    public setStrategy( MemberStrategy strategy){
        this.strategy = strategy;
    }

    /**
     * 计算图书的价格
     * @param booksPrice    图书的原价
     * @return    计算出打折后的价格
     */
    public double quote(double booksPrice){
        return this.strategy.calcPrice(booksPrice);
    }
}

“`
// 客户端的调用
public class Client {

public static void main(String[] args) {
    //选择并创建需要使用的策略对象
    MemberStrategy strategy = new AdvancedMemberStrategy();
    //创建环境
    Price price = new Price(strategy);
    //计算价格
    double quote = price.quote(300);
    System.out.println("图书的最终价格为:" + quote);

    // 创建一个新的使用策略,用新的使用策略代替旧的,这样就可以不用再new一个Price对象
            MemberStrategy strategy2 = new IntermediateMemberStrategy ();
            price.setStratrgy(strategy2);
            quote = price.quote(300);
    System.out.println("图书的最终价格为:" + quote);


}

}

本文参考了:
http://www.cnblogs.com/java-my-life/archive/2012/05/10/2491891.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值