转载于:http://blog.csdn.net/zhonghuan1992/article/details/38885923
根据GOF95,策略模式是对象的行为模式,其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
还记得简单工厂吗?简单工厂就是将创建对象那一块代码提取出来,化身成为一个工厂,然后每当要new对象的时候,直接调用工厂类的创建方法就可以了,不用自己来手动new。其实策略模式有一些相同之处,不过策略模式封装的是策略,也可以说是算法。将这些解决问题的代码块封装起来,当要用时,直接调用就可以了。这个就是策略模式。是不是不难理解啊!
下面我们来看一下策略模式的结构图!
这个模式涉及到三个角色:
环境(Context)角色:持有一个Strategy的引用。
抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
来看一下代码:
上下文对象类
- public class Context {
- private Strategy strategy; //具体策略的对象
- // 构造函数,可以传入一个具体策略对象
- public Context(Strategy strategy){
- this.strategy = strategy;
- }
- public voidcontextInterface(){
- strategy.strategyInterface(); //这里是Context需要使用某个策略对象的方法了
- }
- public void setStrategy(Strategy strategy){
- this.strategy = strategy;
- }
- public StrategygetStrategy(){
- return strategy;
- }
- }
抽象策略角色:
- public interface Strategy {
- //策略方法,具体的实现交给具体的子类决定
- public voidstrategyInterface();
- }
具体的策略类:
- public class ConcreteStrategyA implements Strategy {
- public voidstrategyInterface() {
- //具体的策略(算法)A,等待实现
- }
- }
- public class ConcreteStrategyB implements Strategy {
- public voidstrategyInterface() {
- //具体的策略(算法)B,等待实现
- }
- }
上面的例子不够清楚,让我们用一个比较清晰的例子来说明吧,今天正好去理发了,那个理发店有个这样的规矩,普通会员卡打8折,黄金会员卡打6折。(嗯哼,赤果果的对我的歧视,我~~~~我没有会员卡╮(╯▽╰)╭)
好了,应对这种情况,最好的方式是策略模式啦,这样修改策略的时候,直接在策略类那儿修改或者增加策略的都是很方便的,所以这儿采用策略模式很好。实现代码如下:
- interface Strategy{
- public double cost(double money); //根据传进去的价格,返回一个确切的价格,因为最终价格会根据情况来定嘛
- }
- class PuTong implements Strategy{//原谅我直接上中文拼音了
- @Override
- public double cost(double money)
- {
- return money*0.8;//普通会员打8折
- }
- }
- class Super implements Strategy{
- @Override
- public double cost(double money)
- {
- return money*0.6; //黄金会员嘛,打6折
- }
- }
- public class Client{
- public static void main(String[] args)
- {
- Strategy strategy = new Super();//土豪用的是超级会员卡
- System.out.println("原价100的理发,打完折要付:"+strategy.cost(100)); //土豪理发100会不会便宜点嘿嘿
- strategy = new PuTong();
- System.out.println("原价30的理发,打完折要付: "+strategy.cost(30)); //普通卡理发就这价,差距在哪里,哎~~
- }
- }
何时该使用策略模式:
策略模式嘛,最重要的是,这些策略是否有必要单独拿出来,比如我们经常会使用排序sort方法,它封装了快速排序算法,因为经常使用,非常有必要封装起来,供使用。所以,当我们的策略是一般的,可以抽取出来公用的时候,应当使用策略模式。
策略模式的优点
(1)策略模式提供了管理相关的算法族的办法。策略类的等级结构定义了一个算法或行为族。恰当使用继承可以把公共的代码移到父类里面,从而避免代码重复。
(2)使用策略模式可以避免使用多重条件(if-else)语句。多重条件语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法或行为的逻辑混合在一起,统统列在一个多重条件语句里面,比使用继承的办法还要原始和落后。
策略模式的缺点
(1)客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。换言之,策略模式只适用于客户端知道算法或行为的情况。
(2)由于策略模式把每个具体的策略实现都单独封装成为类,如果备选的策略很多的话,那么对象的数目就会很可观。