这次要说的两个模式,都是行为模式,指的是在程序运行过程中,经过经验总结的行为开发模式。
其次,行为模式再按照类与类间关系的划分,可以划分为四个类型:父子关系(2种)、独立类间关系(4种)、类自身状态(2种)、需要中间类代理(3种)。
本次所说的策略模式与模板模式,都属于父子关系的行为模式。
>什么是策略模式?
策略模式,是指将某个类运行过程中,把核心算法提取出来、封装,使得对象在针对不同的情境可以方便地更换执行策略(算法),使得算法独立变化而不影响客户端的使用。
有那么一点点抽象,那我们举个例子:
大家都接触过排序算法吧,快排桶排堆排,在针对不同的数组时表现各异,那么我们就可以把具体的Sort算法提取出来,做到算法与客户端解耦。
abstruct class SortStrategy{
abstruct fun sort()
}
//具体算法的扩展,如冒泡算和快排
class BubbleSort:SortStrategy{
fun sort(){
//do sort
}
}
class QuickSort:SortStrategy{
fun sort(){
//do sort
}
}
在使用时,客户端获取一个SortStrategy对象,针对不同数组,选择合适的策略(算法)即可,如当我需要用快排时:
var s:SortStrategy = QuickSort()
我们都知道排序有常用的有八大算法,因此可以使劲往下扩展,非常
OCP,用起来维护也方便。
详细的利用策略模式构建排序算法类的例子见此: http://blog.csdn.net/shenpibaipao/article/details/77389222
>什么是模板模式?
先从一个例子引入:泡茶与泡咖啡的例子。
泡茶的流程是:烧水,拿茶壶,放入茶叶,冲泡;
泡咖啡的流程:烧水,拿咖啡壶,放入可可,冲泡。
二者的流程是不是非常接近?,难道我们要写两个类去区分他们?当然不是,模板模式就是为了解决这个问题而存在的。让我们抽象这个过程:
abstruct class DrinkTemplate{
final fun boilWater()
abstruct fun getPot()
abstruct fun putSource()
final fun makeDrink()
}
可以看到,相近的两个步骤被写成了抽象方法,放到具体的子类中去实现。这就是模板方法,是一种有效减少程序中类的数量的开发模式,属于职责细化,符合
SRP和OCP。
所以,模板方法是指:定义一个算法流程的骨架,把一些可变节点延迟到具体的子类中去执行,符合OCP和SRP。
很简单,哪怕之前没研究过设计模式的程序员也会有意无意地使用这种方法使得代码可维护性更强。
>策略模式与模板模式的区别
有人可能注意到了,策略模式和模板模式怎么看着有点类似?其实二者还是不一样的,在具体的细节上有差异:
- 执行流程:模板模式一定是按照一定次序执行程序的,任何一个节点的重载不会影响到这个次序;策略模式则不一定,它只提供了某个情景下的执行策略,是为了优化这个情景而制定的,为了达到需求,只要入口相同,执行顺序不做需求;
- 可变节点:模板模式可变节点大于等于一;策略模式被重载的节点一般唯一;
- 重载侧重点:模板模式要求算法流程中的某几个节点会被替换,但顺序不变;策略模式中整个算法都是可以被替换的。
唯一需要知道区别的,估计就是面试的时候吧?