策略定义
百度百科中,策略一般是指:1. 可以实现目标的方案集合;2. 根据形势发展而制定的行动方针和斗争方法;3. 有斗争艺术,能注意方式方法。这里重点看第一点的解释,也就是一组实现目标的方案方法。
策略模式例子
举个例子,同样是去某个地方(这个地方离你大概10公里),这时候可以选择骑自行车,还可以选择骑电动车或者骑摩托车,甚至是开车。这个例子中采用的交通工具就是这里所说的策略。不同策略达到的效果也不同。骑自行车去花费的时间长,但是可以慢慢欣赏路边的风景。骑电动车次各个之,前提是你的电动车得有足够电支撑你到达目录地。摩托车不需要担心充电的问题,但是要考虑加油的问题,或者如果有3-4人去,一辆摩托就不够了。这时候开车又是比较好的选择。当然了开车的成本最高了,既是耗油最大的又需要担心停车问题。
经过上面这个分析,我们知道各个策略都有着适应的场景,在不同的场景使用着不同的策略才是最优的选择。
我们采用JAVA代码来实现一下这个案例。
代码实现
首先我们定义一个目标,也就是去目的地的方法
public interface GoTarget {
// 去某个地方
void goTarget();
}
再定义一个骑自行车的策略实现类
public class BikeStrategy implements GoTarget{
@Override
public void goTarget() {
System.out.println("ride bike");
}
}
接下来定义一个骑电动车的策略实现类
public class ElectricalBicycleStrategy implements GoTarget {
@Override
public void goTarget() {
System.out.println("ride electrical bicycle");
}
}
然后是骑摩托车的策略实现类
public class MotorcycleStrategy implements GoTarget {
@Override
public void goTarget() {
System.out.println("ride motorcycle");
}
}
最后是开车的策略实现类
public class CarStrategy implements GoTarget {
@Override
public void goTarget() {
System.out.println("drive car");
}
}
现在让我们使用我们喜欢的交通工具去目的地吧
public class TestGoTarget {
public static void main(String[] args) {
GoTarget goTarget = new BikeStrategy();
// 第一次骑车去
goTarget.goTarget();
System.out.println("============我是一条分割线==============");
// 第二次开车去
goTarget = new CarStrategy();
goTarget.goTarget();
}
}
得到的结果是
ride bike
============我是一条分割线==============
drive car
虽然上述例子十分简单,但是这个这个例子的思想才是十分重要的。在main
方法中,我们定义的是GoTarget
这个类,并没有写固定的实现类。这样就可以在运行过程中动态绑定,也就是所谓的多态。这样使用起来非常灵活。这个例子似乎看不出它灵活在哪里,即使写了具体类似乎也没啥很大的影响,那我再举一个例子,在上面的基础上加一部分代码。
public static void main(String[] args) {
GoTarget goTarget = new BikeStrategy();
goTarget.goTarget();
System.out.println("============我是一条分割线==============");
goTarget = new CarStrategy();
goTarget.goTarget();
System.out.println("============我还是一条分割线==============");
complexLogicFunction(goTarget);
}
// 定义了一个复杂逻辑的方法
public static void complexLogicFunction(GoTarget goTarget){
System.out.println("把这里理解为一大段复杂的业务逻辑,可能是校验,查询数据库,做函数运算。。。。。。");
goTarget.goTarget();
System.out.println("做后处理的逻辑,操作数据库,修改数据,拼接结果。。。。");
}
运行结果为:
ride bike
============我是一条分割线==============
drive car
============我还是一条分割线==============
把这里理解为一大段复杂的业务逻辑,可能是校验,查询数据库,做函数运算。。。。。。
drive car
做后处理的逻辑,操作数据库,修改数据,拼接结果。。。。
上面的代码多定义了一个复杂的逻辑方法函数,在这个方法函数中,先进行了一系列复杂的操作,然后调用了goTarget.goTarget()
方法,调用完成后,又处理了一堆后处理逻辑。
这个时候,传入接口类的好处就体现出来了,因为现在我们这里是drive car
,以后即使换成ride bike
或者其他的时候,这个复杂的函数也不需要修改,只需要改一下创建的实现类即可。
这也是面向对象的核心之一,面向接口编程,而不是面向具体的实现。
但是这里只是体现了面向接口编程的好处,好像和策略无关,别急,我们的业务继续变更。
现在的业务需求是要去更远的地方看看,目的地定在了1000公里之外的地方。如果开车,到达目的地花费的时间长不说,开车还累。所以,要变换下交通工具,比如说坐高铁去。这个时候策略的优势就体现出来了。
定义新的策略,只需要增加一个策略类,简简单单改一行代码,就可以实现坐高铁去目的地了。
其实这也就是策略模式的核心:改变一下策略,其他的内容都无需改变,就可以实现目的。
总结
策略模式在平时代码设计中使用的非常的广泛。比如数据库的驱动类,spring
中的ApplicationContext
。都是策略模式的体现。特别是在多种业务规则去实现同一种目的的时候,策略模式的优势就体现出来。而且这样不会显得代码过多或者过于混乱。而是变得更加清晰,只要知道该在什么时候使用什么策略即可。程序的可扩展性也会得到提高。