一)故事
二)定义
定义一个操作中的算法和框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法和某些特定步骤。
三)代码例子
共计两个类:1)抽象模板类;2)具体模板类(可多个);
1)抽象模板类
2)具体模板类(可多个)
场景使用例子
四)优点
1)封装不变部分,扩展可变部分
把认为是不变部分的算法封装到父类实现,而可变部分是则可以通过继承来继续扩展,在悍马模型例子中,是不是就非常容易扩展?例如增加一个H3型号的悍马模型,很容易啊,增加一个子类,实现父类的基本方法就可以了。
2)提取公用部分代码,便于维护
我们例子中刚刚走过的弯路就是最好的证明,如果我们不抽取到父类中,任由这路散乱的代码发生,想想后果是什么样子?维护人员为了修正一个缺陷,需要到处查找类似的代码!
3)行为由父类控制,子类实现
基本方法是由子类实现的,因此子类可以通过扩展的方式增加相应的功能,符合开闭原则。
五)缺点
六)使用场景
1)多个子类有公有的方法,并且逻辑基本相同时。
2)重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
3)重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数(见“模板方法模式的扩展”)约束其行为。
七)注意事项
八)扩展
九)总结
我就一直没有搞懂为什么要用父类调用子类的方法。如果一定要调用子类,那为什么要继承呢?搞不懂。其实这个问题可以换个角度去理解,父类建立框架,子类重写了父类部分的方法后,再调用从父类继承的方法,产生不同的结果(而这正是是模板方法模式)。这是不是也可以理解为父类调用了子类的方法呢?你修改了子类,影响了父类行为的结果,曲线救国的方式实现了父类依赖子类的场景,模板方法模式就是这种效果。
模板抽象类定义基本方法(抽象方法)和模板方法(具体方法),模板方法可调用基本方法完成业务逻辑,基本方法(抽象方法)由子类实现。这两个类就构成了模板方法模式。
二)定义
定义一个操作中的算法和框架,而将一些步骤延迟到子类中。使得子类可以不改变一个算法的结构即可重定义该算法和某些特定步骤。
三)代码例子
共计两个类:1)抽象模板类;2)具体模板类(可多个);
1)抽象模板类
/**
* 抽象模板类
*
* @author levovo
*/
public abstract class AbsClass {
// 基本方法
protected abstract void doSomething();
// 基本方法
protected abstract void doAnything();
// 模板方法
public void templateMethod() {
System.out.println("AbsClass()->templateMethod()");
// 调用基本方法,完成相关的逻辑
this.doAnything();
this.doSomething();
}
}
2)具体模板类(可多个)
/**
* 具体模板类
*
* @author levovo
*/
public class ConcreteClass1 extends AbsClass {
// 实现基本方法
@Override
protected void doSomething() {
// 业务逻辑处理
System.out.println("ConcreteClass1()->doSomething()");
}
@Override
protected void doAnything() {
// 业务逻辑处理
System.out.println("ConcreteClass1()->doAnything()");
}
}
/**
* 具体模板类
*
* @author levovo
*/
public class ConcreteClass2 extends AbsClass {
// 实现基本方法
@Override
protected void doSomething() {
// 业务逻辑处理
System.out.println("ConcreteClass2()->doSomething()");
}
@Override
protected void doAnything() {
// 业务逻辑处理
System.out.println("ConcreteClass2()->doAnything()");
}
}
场景使用例子
/**
* 场景使用例子
*
* @author levovo
*/
public class Client {
public static void main(String[] args) {
AbsClass class1 = new ConcreteClass1();
AbsClass class2 = new ConcreteClass2();
// 调用模板方法
class1.templateMethod();
class2.templateMethod();
}
}
四)优点
1)封装不变部分,扩展可变部分
把认为是不变部分的算法封装到父类实现,而可变部分是则可以通过继承来继续扩展,在悍马模型例子中,是不是就非常容易扩展?例如增加一个H3型号的悍马模型,很容易啊,增加一个子类,实现父类的基本方法就可以了。
2)提取公用部分代码,便于维护
我们例子中刚刚走过的弯路就是最好的证明,如果我们不抽取到父类中,任由这路散乱的代码发生,想想后果是什么样子?维护人员为了修正一个缺陷,需要到处查找类似的代码!
3)行为由父类控制,子类实现
基本方法是由子类实现的,因此子类可以通过扩展的方式增加相应的功能,符合开闭原则。
五)缺点
六)使用场景
1)多个子类有公有的方法,并且逻辑基本相同时。
2)重要、复杂的算法,可以把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
3)重构时,模板方法模式是一个经常使用的模式,把相同的代码抽取到父类中,然后通过钩子函数(见“模板方法模式的扩展”)约束其行为。
七)注意事项
八)扩展
九)总结
我就一直没有搞懂为什么要用父类调用子类的方法。如果一定要调用子类,那为什么要继承呢?搞不懂。其实这个问题可以换个角度去理解,父类建立框架,子类重写了父类部分的方法后,再调用从父类继承的方法,产生不同的结果(而这正是是模板方法模式)。这是不是也可以理解为父类调用了子类的方法呢?你修改了子类,影响了父类行为的结果,曲线救国的方式实现了父类依赖子类的场景,模板方法模式就是这种效果。
模板抽象类定义基本方法(抽象方法)和模板方法(具体方法),模板方法可调用基本方法完成业务逻辑,基本方法(抽象方法)由子类实现。这两个类就构成了模板方法模式。