前言
策略模式的最多的被用在算法中。针对同一个功能有多种实现方式,比如排序算法。通常策略模式就是把同一个功能或算法等抽象为一个接口方法。具体的实现用单独的类implements这个接口来实现。这样做的好处是OCP单一原则,可扩展、可维护性很高。
策略模式定义
对同一问题或方法的不同处理方式单独封装起来。
策略模式例子
最近房租涨的那么猛,我们就写一个计算不同地方的平均房租的例子。抽象出来的方法就是计算平均房租。
这里的Calculation就是我们的计算策略
public interface Calculation {
int calculationAverageRent();
}
然后我们算一下深圳和北京这两个地方的平均房租。当然具体的算法肯定很复杂,这里只是模拟就省略了。看代码
public class ShenzhenAvaerageRent implements Calculation {
@Override
public int calculationAverageRent() {
//这里只是模拟,省略具体怎么算的。
return 3000;
}
}
public class BeijingAverageRent implements Calculation {
@Override
public int calculationAverageRent() {
//这里只是模拟,省略具体怎么算的。
return 5000;
}
}
我们分别写了两个不同的类,BeijingAverageRent和ShenzhenAvaerageRent来计算北京和深圳的平均房租,这样都是计算平均房租,具体的复杂实现却互不影响。然后写一个具体的计算平均房租的类。
public class CalculationAverageRent {
private Calculation calculation;
public void setCalculation(Calculation calculation) {
this.calculation = calculation;
}
public int getAverageRent() {
return calculation.calculationAverageRent();
}
}
至此策略模式的整个结构就呈现了。就是为了把BeijingAverageRent和ShenzhenAvaerageRent这两个具体的方法独立出来。实现解耦。最后调用就很简单了
ShenzhenAvaerageRent shenzhenAvaerageRent = new ShenzhenAvaerageRent();
BeijingAverageRent beijingAverageRent = new BeijingAverageRent();
CalculationAverageRent calculationAverageRent = new CalculationAverageRent();
calculationAverageRent.setCalculation(shenzhenAvaerageRent);
int shenzhen = calculationAverageRent.getAverageRent();
calculationAverageRent.setCalculation(beijingAverageRent);
int beijing = calculationAverageRent.getAverageRent();
Log.d("Strategy","shenzhen average rent = " + shenzhen);
Log.d("Strategy","beijing average rent = " + beijing);
输出
D/Strategy: shenzhen average rent = 3000
D/Strategy: beijing average rent = 5000
策略模式小结,为啥使用策略模式
到这里策略模式的例子就讲完了,结构特别简单,但它带来的好处也很明显,算法独立,扩展,修改都很方便,俗称采用不同的策略,由此策略模式名字由此而来。如果不用策略模式,你或许就直接定义两个计算的类来实现,但是,你想想你在调用的时候,你只能是用if else 或者switch来选择北京还是深圳,然后再去调用算法。显然没有策略模式的代码优雅,且扩展性也没这么好。so,以后用起来吧。
结束语
策略模式多被用在算法中,用来分离算法,在相同的的行为抽象下有不同的实现策略。是开闭原则的绝佳演示。
优点:
1、结构清晰,简单直观
2、扩展方便,耦合度低
3、封装彻底,数据更安全
缺点:
策略如果过多,子类变得繁多
在最后的最后,笔者留给读者一个思考,用抽象类代替接口,如何实现策略模式类似的结构代码。并且思考抽象和接口的差别。