今天继续写设计模式,设计模式这个东西写起来比较容易,但是用起来还是有一定的难度的,在很多时候,如果是全新的开发一个新东西,还可以从软件设计上引入一些设计模式来增加软件对开闭原则的支持,其实,话又说回来了,生硬的使用一个或者两个设计模式,未必让你设计的软件在可维护以及代码的优雅度上有所增加,真正的高手使用这些东西是在无形之中的,多种设计模式以及设计原则混合使用,无形胜有形!
策略模式,是对象的行为模式,其用意是针对一组算法,将每个算法封装到具有共同接口的独立的类中,从而使得他们可以互相替换,策略模式可以使算法在不影响客户端的情况下发生变化。
策略模式所解决的问题就是需求变化的问题,它将算法的具体行为与算法的环境分开,环境类负责维护和查询行为类,具体的行为则在各种具体的行为类中提供,当有新的需求增加的时候,只需要添加新的行为类,然后在客户端使用即可,是不是有一种可插拔的感觉。
对于上面说了这么多,就是在表达一个意思,想把系统设计成支持开闭原则的系统,利于以后的维护和扩展,不仅是这个设计模式是这样的,以前以及以后要提到的设计模式,其实,都是为懒人服务的,懒人开发的东西,想以最快最简单的方式满足各种需求的变化,说了这么多了,到底策略模式是一个什么样的东西呢?下面是策略模式简单的结构类图:
图01 设计模式结构类图
package com.plabmedia.strategy;
public class Context {
private Strategy strategy;
public Context(Strategy strategy){
this.strategy = strategy;
}/**
* 策略方法
*/
public void contextMethod(){
strategy.strategyMethod();
}}
package com.plabmedia.strategy;
public interface Strategy {
/**
* 策略方法
*/
public void strategyMethod();
}package com.plabmedia.strategy;
public class ConcreteStrategyA implements Strategy{
@Override
public void strategyMethod() {
//在这里增加需要的策略算法
System.out.println(“concretestragegyA”);
}}
package com.plabmedia.strategy;
public class ConcreteStrategyB implements Strategy{
@Override
public void strategyMethod() {
//在这里增加需要的策略算法
System.out.println(“concretestragegyB”);
}}
package com.plabmedia.strategy;
public class ConcreteStrategyC implements Strategy{
@Override
public void strategyMethod() {
//在这里增加需要的策略算法
System.out.println(“concretestragegyC”);
}}
package com.plabmedia.strategy;
public class Client {
public static void main(String[] args){
Context context = new Context(new ConcreteStrategyA());
context.contextMethod();context = new Context(new ConcreteStrategyB());
context.contextMethod();context = new Context(new ConcreteStrategyC());
context.contextMethod();
}}
从上面的代码中看出来一些什么了么?从上面的代码可以看出,具体的策略类只负责自己的行为实现,也就是告诉系统我是做这个事情的,谁让我来做这个事情,我不管,只要有人招呼我,我都可以做,招呼具体策略做事情的是客户端,也就是由客户端来决定具体的策略,同时,为了达到不同策略之间的互换,策略模式不适合处理嵌套算法,也就是同时处理多于一个的算法。
前面对策略模式的介绍也算告一个段落了,大家也都比较清楚策略模式到底是一个什么东东了,用来完成什么样的事情,那现在我们思考几个问题:
1.什么情况下应当使用策略模式?
- 当系统中有很多类,它们之间的区别仅仅是它们的行为,可以通过策略模式把这些类的行为转换成不同的策略,供系统调用;
- 在系统中,需要动态的选择多种算法中的一种,那么可以把这些算法包装成一个个具体的策略,然后为这些策略提供一个统计的接口(Context)进行调用;
- 当系统要求算法的数据和行为对客户端是透明的,策略模式可以达到这一点;
- 当系统中存在很多条件判断语句的时候,你可以考虑使用策略模式来消灭判断语句,进而体现面向对象设计的概念。
2.策略模式的优点:
- 在上面的例子中,抽象策略使用的是接口,在实际应用中,我们也可以使用抽象类作为抽象策略,然后将策略的公共代码转移到抽象策略中实现,达到代码复用的效果,同时,它又比继承灵活(算法独立,可以任意扩展);
- 策略模式可以避免多重的条件判断语句,使系统灵活,易于扩展。
3.策略模式的缺点
- 策略模式的使用:由客户端来决定具体使用哪个策略类,这就需要客户端对具体的策略类有所了解,从另一个角度上来讲,策略类只适合于客户端了解策略类行为的情况下
- 每增加一个行为,就会产生一个新的策略类,这样会在系统中造成很多的策略类。
上面的这些东西,也大概的把策略模式介绍了一下,其实,具体使用的时候,还是要大家去判断,比如策略模式与工厂方法,到底用哪一个呢?在涉及到代码复用的时候,是使用策略模式还是模版方法呢?这些问题都没有一定的答案,要我们在工作中根据具体问题具体分析,正常的情况下是,为了达到某种目的,多种设计模式同时使用。