策略模式
策略模式是对象行为型模式,它可以定义一系列的算法,并且将每个算法封装起来,在使用时可以相互替换,使得算法可以独立于客户的使用而变化。例如:今天我要从北京去深圳,我可以选择坐火车、坐高铁、坐飞机等方式出现,这样每一种方式耗费的时间不同,但是我能达到的目的都是相同的,我从北京到了深圳只是我耗费的时间不同而已,这样我就可以把三种出行方式分别封装到3个类里面根据不同情况可以*变换算法,而作为客户的我都可以达到我想要的目的。这个就是策略模式。
策略模式的适用性
-
系统中存在许多相关的类仅仅是行为有异,策略模式可以提供一种用多个行为中的一个来配置一个类的方法。
-
算法使用客户不应该知道的数据,这样可以避免暴露复杂的与算法有关的数据结构。
-
一个类的行为可以通过多种算法来实现,在实现这个行为时,算法可以*切换。
策略模式的结构图
策略模式中总共有三个角色:
1、抽象策略角色(Strategy):定义所有支持的算法的公共接口。
2、具体策略角色(ConcreteStrategy):实现Strategy接口并且实现自身的算法。
3、上下文(Context):维护一个Strategy对象的引用,同时定义一个接口通过Strategy来访问算法的数据。
策略模式的示例
定义一个抽象策略角色并且声明其算法的方法
public interface Strategy { public void Algorithminterface(); }
然后具体策略角色实现抽象策略角色,具体通过三个类来实现接口Strategy,分别实现坐火车、坐高铁、坐飞机的算法
public class ConcreteStrategyA implements Strategy { @Override public void Algorithminterface() { System.out.println("坐火车从北京到深圳,耗时23个小时"); } }
public class ConcreteStrategyB implements Strategy { @Override public void Algorithminterface() { System.out.println("坐高铁从北京到深圳,耗时8个小时"); } }
public class ConcreteStrategyC implements Strategy { @Override public void Algorithminterface() { System.out.println("坐飞机从北京到深圳,耗时3个小时"); } }
最后创建一个Context
public class Context { private Strategy strategy; public Context(Strategy strategy) { this.strategy = strategy; } public void ContextInterface() { this.strategy.Algorithminterface(); } }
Client分别调用三种算法的情形
public class Client { public static void main(String[] args) { Strategy strategy1=new ConcreteStrategyA(); Strategy strategy2=new ConcreteStrategyB(); Strategy strategy3=new ConcreteStrategyC(); /*客户端调用坐火车的算法*/ Context context1=new Context(strategy1); context1.ContextInterface(); /*客户端调用坐高铁的算法*/ Context context2=new Context(strategy2); context2.ContextInterface(); /*客户端调用坐飞机的算法*/ Context context3=new Context(strategy3); context3.ContextInterface(); } } /* 运行结果: 坐火车从北京到深圳,耗时23个小时 坐高铁从北京到深圳,耗时8个小时 坐飞机从北京到深圳,耗时3个小时*/
策略模式的优缺点
策略模式通过封装执行相同行为的不同方式的算法,上例我们可以看到调用不同的算法方式都是相同的,只不过传递进去的算法示例不一样,这样在使用过程中可以任意的选择不同的实现算法,例如我们去商场购物商场可能会推出不同的活动:1、购物消费打8折;2、满100减30;3、在上述基础上还可以进行优惠券抵扣。这样实际上我们可以把三种方式封装成三种算法对象,在需要进行那种优惠活动时只需要选择不同的算法即可,而客户用关心算法的具体实现和使用的数据,隐藏了内部的实现。
策略模式虽然解耦了算法与客户端,但是针对每种算法都需要创建一个新的类,如果算法会慢慢的变多,会使得系统中的类逐渐变得很多难以维护。