设计模式的目的是为了增加代码的可重用性和提高软件的可维护性,软件开发中维护和更新的工作量比一开始的工作量大得多,所以说一个好的设计模式有时候是非常必要的,首先让我们来简单介绍设计模式中的策略模式。本系列中的模式来源于Head First设计模式一书中,加上自己学习过程中的心得体会。
策略就是用来解决问题的,对于一个问题不同个体会有不同表现,我们就可以采用策略模式。比如书中提到的鸭子的模型,鸭子怎么叫就是一个要解决的问题,不同的鸭子有不同的叫法,我们可以把鸭子叫的方式独立出来写成一个接口,然后对这个接口实现各种策略,比如呱呱叫、嘎嘎叫等,要用到鸭子叫的时候就直接调用这些策略就ok了。
下面具体看一下用JAVA如何实现这种模式,先看一下类图
图中对策略进行了封装,封装成Strategy接口,接口中抽象方法work代表要怎么执行任务,StrategyOne、StrategyTwo、StrategyThree实现Strategy接口并为抽象方法work提供了不同实现,所以它们处理work的策略不一样。StrategyMode类performStrategy用于对外暴露功能,strategy可配置为具体策略StrategyOne、StrategyTwo、StrategyThree中的一种,然后就可以实现不同的功能。
其实策略模式本质上定义了一堆算法簇,然后根据需要实现的功能,只要在算法簇中选择合适算法即可。
下面给出具体各个类的实现:
Strategy接口的实现
package StrategyMode;
public interface Strategy {
//实现策略的方法
public void work();
}
StrategyMode类的实现
package StrategyMode;
public class StrategyMode {
private Strategy strategy = null;
public StrategyMode(){
//选择策略
strategy = new StrategyOne();
//strategy = new StrategyTwo();
//strategy = new StrategyThree();
}
public void performStrategy(){
strategy.work();
}
public static void main(String [] args){
StrategyMode mode = new StrategyMode();
mode.performStrategy();
}
}
StrategyOne、StrategyTwo、StrategyThree的实现
package StrategyMode;
class StrategyOne implements Strategy {
@Override
public void work() {
//do something
System.out.println("I am strategy one!");
}
}
class StrategyTwo implements Strategy {
@Override
public void work() {
// do something
System.out.println("I am strategy two!");
}
}
class StrategyThree implements Strategy {
@Override
public void work() {
// do something
System.out.println("I am strategy three!");
}
}
策略模式优缺点:
优点
1、 提供了一种替代继承的方法,而且既保持了继承的优点(代码重用),还比继承更灵活(算法独立,可以任意扩展);
2、 避免程序中使用多重条件转移语句,使系统更灵活,并易于扩展;
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合;
4、 易于进行单元测试,各个算法区分开,可以针对每个算法进行单元测试;
缺点
1、 因为每个具体策略类都会产生一个新类,所以会增加系统需要维护的类的数量;
2、 选择何种算法需要客户端来创建对象,增加了耦合,这里可以通过与工厂模式结合解决该问题;
3、 程序复杂化。
设计原则:
1.找出应用中可能变化之处,把它们独立出来,不要跟那些不能独立的代码混在一起;
2.针对接口编程,不针对实现编程;
3.多用组合,少用继承。