模板方法模式,是很简单的一种设计模式,我们在现实开发中可能经常用到,但是我们并没有意识到这是一种设计模式。首先,来看一下模板方法模式的定义:
Define the skeleton of an algorithm in an operation,deferring some steps to subclasses,Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm's structure.(定义一个操作中的算法框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。)
模板方法模式的类图:
看类图就可以知道有多简单,只是用到了继承机制。下面来看一下通用的代码实现:
public abstract class AbstractTemplateMethod{
//基本方法
protected abstract void doSomething1();
//基本方法
protected abstract void doSomething2();
//模板方法
public final void templateMethod(){
//调用基本方法,根据需求完成相应逻辑
this.doSomething1();
this.doSomething2();
}
}
具体模板方法实现类:
public class TemplateMethod1 extends AbstractTemplateMethod1{
//基本方法
protected void doSomething1(){
//逻辑代码
...
}
//基本方法
protected void doSomething2(){
//逻辑代码
...
}
}
具体需要些什么样的模板方法的具体实现类,根据需求来进行具体实现,具体调用代码:
public class TestMain {
public static void main(){
new TemplateMethod1().templateMethod();//将按照具体子类中实现的逻辑执行
}
}
抽象模板中的基本方法最好设计为protected类型,不需要暴露的属性或者方法尽量设置为private类型.。
是不是so easy?来看一下模板方法模式有哪些优缺点吧。
优点:
1.封装不变部分,扩展可变部分;
2.提取公共部分代码,便于维护;
3.行为由父类控制,子类负责实现。
缺点 :
按照习惯,抽象类都是负责声明最抽象、最一般的事物属性和方法,实现类完成具体的事物属性和方法,但是模板方法模式却反了,抽象类定义了部分抽象方法,由子类实现,子类执行的结果影响了父类的结果,也就是子类对父类产生了影响,增加了代码阅读的难度。
模板方法模式使用场景:
钩子方法,是在抽象类中返回boolean值,从而通过判断来影响模板方法的执行结果的方法。
例如:
public abstract class AbstractTemplateMethod{
//基本方法
protected abstract void doSomething1();
//基本方法
protected abstract void doSomething2();
//钩子方法
protected abstract boolean isFlag();
//模板方法
public final void templateMethod(){
//调用基本方法,根据需求完成相应逻辑
this.doSomething1();
if(isFlag()){ //影响到模板方法的执行结果 <pre name="code" class="java"> this.doSomething2();
} }}
这里有个问题,当我们想要控制模板方法中基本方法执行顺序时,我们应该怎么解决呢?(这个可以加一个list列表来定义执行顺序)
重要说明:我在所有的设计模式通用代码中使用的void修饰符来修饰函数,并不是代表函数不能用返回值。。。这个方法都是看具体需求、具体场景实现的。