相关链接:
【设计模式】专栏:【设计模式】专栏
相关例子可下载: Java常用设计模式例子
模板方法模式
模板方法模式(Template Method Pattern),定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。它是一种行为型模式。
一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
优点
-
它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
-
它在父类中提取了公共的部分代码,便于代码复用。
-
部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合“开-闭原则”。
缺点
-
对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,间接地增加了系统实现的复杂度。
-
父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
-
由于继承关系自身的缺点,如果父类添加新的抽象方法,则所有子类都要改一遍。
模板方法模式的角色
模板方法模式需要注意抽象类与具体类之间的协作。它用到了虚函数的多态性技术以及“不用调用我,让我来调用你”的反向控制技术。
模板方法模式主要包含以下角色:
1)抽象类/抽象模板(Abstract Class)
抽象模板类,负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。这些方法的定义如下:
① 模板方法
定义了算法的骨架,按某种顺序调用其包含的基本方法。
② 基本方法
是整个算法中的一个步骤,包含以下几种类型
-
抽象方法:在抽象类中声明,由具体子类实现
-
具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。
-
钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。
2)具体子类/具体实现(Concrete Class)
具体实现类,实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤。
示例代码
抽象类
/**
* 模板方法模式——抽象类/抽象模板
*
* (奶茶)
*
*/
public abstract class MilkTea {
/**
* 模板方法
*/
public void makingMilkTea() {
// 加茶
tea();
// 加奶
milk();
// 加配料
if (needToAddCondiments()) {
addCondiments();
}
}
/**
* 抽象方法,添加配料
*/
public abstract void addCondiments();
/**
* 具体方法
*/
public void tea() {
System.out.println("第一步,加红茶");
}
/**
* 具体方法
*/
public void milk() {
System.out.println("第二步,加牛奶");
}
/**
* 钩子方法,用来判断是否需要添加配料
* @return
*/
public boolean needToAddCondiments() {
return true;
}
}
具体子类
/**
* 模板方法模式——具体子类/具体实现
*
* (珍珠奶茶)
*
*/
public class PearlMilkTea extends MilkTea{
@Override
public void addCondiments() {
System.out.println("第三步,加珍珠");
}
}
/**
* 模板方法模式——具体子类/具体实现
*
* (烧仙草)
*
*/
public class GrassJellyMilkTea extends MilkTea{
@Override
public void addCondiments() {
System.out.println("第三步,加烧仙草料");
}
}
/**
* 模板方法模式——具体子类/具体实现
*
* (纯奶茶)
*
*/
public class PureMilkTea extends MilkTea{
@Override
public void addCondiments() {
}
@Override
public boolean needToAddCondiments() {
return false;
}
}
测试类
/**
* 模板方法模式
*
*/
public class TemplatePatternDemo {
public static void main(String[] args) {
System.out.println("===制作珍珠奶茶===");
MilkTea milkTea = new PearlMilkTea();
milkTea.makingMilkTea();
System.out.println("===制作烧仙草===");
milkTea = new GrassJellyMilkTea();
milkTea.makingMilkTea();
System.out.println("===制作纯奶茶===");
milkTea = new PureMilkTea();
milkTea.makingMilkTea();
}
}
结束语
1、更多设计模式内容请看【设计模式】专栏
2、相关例子代码可下载: Java常用设计模式例子
PS: 【 Java常用设计模式例子 】 内已包含 【设计模式】专栏 里所涉及的代码,需要代码的同学可以下载哦,如果之前已下载过的同学,就不需要重复下载啦~
以上内容如有不正确或需要补充的地方,还请多多请教,会及时更新改正~
欢迎评论~ 感谢点赞~