《设计模式》- 模板模式

模板模式在诸多模式中算是比较简单的一个,即便一个新手,也能很快的上手和使用。虽然简单,但合理的在项目中使用带来的好处可不小。软件设计中有个很重要的原则:DRY(Don‘t Repeat Yourself),重复有很多种,比如代码重复,逻辑重复,而模板模式的最拿手的就是消除逻辑重复。

我们先看一下模板模式的定义:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中去实现。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。只要你学习过任何一门面向对象语言,那么理解上面的定义肯定不是问题。

来看看模式的UML类图:

AbstractClass是一个抽象类,其中templateMethod是一个final方法,封装了具体的算法实现步骤、过程,其内部调用了其它方法。abstractMethod1与abstractMethod2是抽象方法,其具体实现由具体的子类决定,这样子类就可以在不改变算法结构的情况下,重新定义算法中的某些步骤。值得一提的是hook方法,它是一个钩子方法,在父类中会提供一个默认的实现,子类可以有选择的决定是否要覆盖钩子方法。简单而言,钩子让子类有机会修改算法中的某些步骤,是否使用钩子完全取决于业务。

我们来看一个例子。

饮料制作
饮料 牛奶 咖啡
1. 把杯子洗干净。

2. 把水煮沸。

3. 把饮料放入杯子。

4. 把开水倒入杯中。

5. 加调料。

6. 搅拌。

1. 把杯子洗干净。

2. 把水煮沸。

3. 把奶粉放入杯子。

4. 把开水倒入杯中。

5. 加糖。

6. 搅拌。

1. 把杯子洗干净。

2. 把水煮沸。

3. 把咖啡放入杯子。

4. 把开水倒入杯中。

5. 加糖、伴侣。

6. 搅拌。

饮料(Beverage是一个抽象类,make方法封装了饮料的制作流程,但具体制作什么饮料,加不加调料、加什么调料由给子类去决定,addCondiment方法是一个钩子,默认什么都不做。

public abstract class Beverage {
	public final void make() {
		System.out.println("把杯子洗干净。");
		System.out.println("把水煮沸。");
		this.addBeverage();
		System.out.println("把水倒入杯中。");
		this.addCondiment();
		System.out.println("搅拌。");
	}

	protected abstract void addBeverage();
	protected void addCondiment() {
		//默认什么调料都不加。
	}
}

牛奶(Milk是一个实现类,仅实现addBeverage方法;Coffee也是一个实现类,实现了addBeverage,并且覆盖了addCondiment方法(不加糖咖啡太苦啦)。

public class Milk extends Beverage {

	@Override
	protected void addBeverage() {
		System.out.println("把奶粉倒入杯口。");
	}

}
public class Coffee extends Beverage {

	@Override
	protected void addBeverage() {
		System.out.println("把咖啡倒入杯口。");
	}

	@Override
	protected void addCondiment() {
		System.out.println("加糖和咖啡伴侣。");
	}

}

运行结果:

public static void main(String[] args) {
	Beverage milk = new Milk();
	Beverage coffee = new Coffee();

	System.out.println("做牛奶......");
	milk.make();
	System.out.println("\n做咖啡......");
	coffee.make();
}
做牛奶......
把杯子洗干净。
把水煮沸。
把奶粉倒入杯口。
把水倒入杯中。
搅拌。

做咖啡......
把杯子洗干净。
把水煮沸。
把咖啡倒入杯口。
把水倒入杯中。
加糖和咖啡伴侣。
搅拌。

JDK中有哪些使用模板模式的部分?

像Collections.sort、Arrays.sort等方法,都需要一个实现Comparator接口的对象来决定如何比较对象(实现compare方法);

又如File.listFiles方法需要一个实现FileFilter接口的对象来决定如何过滤文件(通过实现accept方法),在JDK中类似的场景还有很多,这里就不一一例举了。

时间: 2025-01-02 16:11:59

《设计模式》- 模板模式的相关文章

12. 星际争霸之php设计模式--模板模式

题记==============================================================================本php设计模式专辑来源于博客(jymoz.com),现在已经访问不了了,这一系列文章是我找了很久才找到完整的,感谢作者jymoz的辛苦付出哦! 本文地址:http://www.cnblogs.com/davidhhuan/p/4248192.html============================================

PHP设计模式——模板模式

声明:本系列博客参考资料<大话设计模式>,作者程杰. 模板模式准备一个抽象类,将部分逻辑以具体方法以及具体构造形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现.先制定一个顶级逻辑框架,而将逻辑的细节留给具体的子类去实现. UML类图: 角色: 抽象模板角色(MakePhone):抽象模板类,定义了一个具体的算法流程和一些留给子类必须实现的抽象方法. 具体子类角色(XiaoMi):实现MakePhone中的抽象方法,

C# - 设计模式 - 模板模式

模板模式 问题场景 咖啡和茶派生于抽象类饮料,咖啡和茶都具有烧水的方法,所以可以将烧水的方法提取到抽象类饮料中去实现,而咖啡具有一个向杯子加咖啡粉的方法,茶具有一个向杯子加茶叶的方法,看起来两个方法是不同的逻辑,而抽象类在很多地方都被其它类型所引用,也即其它类型都会调用抽象类而非其子类,以便解耦依赖.所以,我们应该尽量将看起来不一样但有共同点的行为提取到抽象类中定义成抽象成员,抽象成员就像模板,模板总是靠子类帮抽象类去填充实现,这样,在运行时,调用抽象实例就可以得到这些具体的实现了. 总结模式

设计模式——模板模式(C++实现)

模板模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 模板模式通过把不变的行为搬移到超类,去除子类中的重复代码来体现它的优势. 通过继承和多态来实现. 行为型模式. spp业务框架中的server_task(CServerTask类)就是这么一个东西.非常常用的一个模式. 使用场景: 1.有多个子类共有的方法,且逻辑相同. 2.重要的.复杂的方法,可以考虑作为模板方法. 1 #include <iostream>

[工作中的设计模式]模板模式

一.模式解析 准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现.这就是模板方法模式的用意 模板模式的关键点为: 1.有一个父类,将整体业务逻辑和公用方法进行封装: 2.父类将具体的有差异的业务定义为抽象方法: 3.子类继承父类后,实现这些抽象方法,完成对自己业务流程的: 4.子类不可以改变父类的整体业务逻辑流程: 5.子类也可以覆盖父类中其他方法,实现定制化业务

设计模式——模板模式

模板模式: 准备一个抽象类,讲部分逻辑以具体方法的形式实现,然后声明一些抽象方法交由子类实现剩余逻辑,用钩子方法给予子类更大的灵活性.最后将方法汇总构成一个不可改变的模板方法. 适用场景 1 算法或操作遵循相似的逻辑 2 重构时(把相同的代码抽取到分类) 优势: 1 封装性好 2 复用性好 3 疲敝细节 4 便于维护 缺点 1   继承 源码: RefreshBeverage package com.imooc.pattern.template; /**  * 抽象基类,为所有的子类提供一个算法

JAVA设计模式-模板模式

模板模式作用 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 主要解决:一些方法通用,却在每一个子类都重新写了这一方法. 何时使用:有一些通用的方法. 如何解决:将这些通用算法抽象出来. 关键代码:在抽象类实现,其他步骤在子类实现. 示例代码: Exam.java /** * @Classname Exam * @Description 考试抽象类 * @Created by xiangty */public abs

[设计模式]模板模式

  [示例一]回家过春节 原理 使用继承,子类中不需要实现那些重复的订票和庆祝团圆的代码了,避免了代码的重复:子类实现了不同方式的回家方法,把它栓入(hook)到父类中去,实现了完整的回家过年的逻辑. 架构图 源代码 HappyPeople.java package pattern.part1.chapter2.template; public abstract class HappyPeople { public void celebrateSpringFestival() { subscri

.NET开发设计模式-模板模式

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Pay { /// <summary> /// 付款成功回调 /// </summary> public class PayNotify { /// <summary> /// 执行付款操作 /// 对外只提供该接口 //

设计模式之模板模式 template

设计模式 模板模式如果有一个流程如下step1();step2();step3();step4();step5();其中step3() step5()是需要用户自己编写使用其他步骤是固定的那么可以写成 // 11111.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #include <memory> using namespace std; class Lib { public: