设计模式之模板方法模式

模板方法模式.zip 用模板方法模式实现Menu的设计,根据客户输入的要求完成: ①可以选择饮料:咖啡或者茶; ②根据顾客要求,其饮料是否要添加进调料 “y”就表示要在所选择咖啡中添加sugar,milk; 或者所选择茶中添加lemon; “n”表示什么都不需要添加 立即下载

      在模板(Template Pattern)中,一个抽象类公开定义了执行它的方式/模板,它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行,这种类型的设计模式属于行为型设计模式。今天我们就来一起学习探究下设计模式中的模板方法模式,下面是我们今天要学习的内容大纲



一、模板方法模式简单介绍

意图:定义一个操作中的算法骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤

主要解决:一些方法通用,却在每一个子类都重写了这一方法。

何时使用:有一些通用的方法。

如何解决:将这些通用算法抽象出来。

关键代码:在抽象类实现,其它步骤在子类实现。

使用场景:1)多个子类有共有的方法,并且逻辑基本相同时

               2)重要复杂的算法,可以把核心算法设计为模板方法

               3)重构时模板方法模式是一个经常使用的模式

注意事项:为防止恶意操作,一般模板方法都加上 final 关键字。


二、模板方法模式具体演示流程


这里我们通过在一家饮料店喝咖啡喝茶来慢慢进行演绎,在饮料店里,茶和咖啡的冲泡方式非常相似,如下:

咖啡冲泡法:

1)把水煮沸

2)用沸水冲泡咖啡

3)把咖啡倒进杯子

4)加糖和牛奶

茶冲泡法:

1)把水煮沸

2)用沸水冲泡茶

3)把茶倒进杯子

4)加柠檬

从上面的步骤我们可以看到,咖啡喝茶的冲泡方法大致上是一样的

接下来我们来搞定咖啡和茶的类:

咖啡类:

/**
 * 咖啡类
 * 
 * @author qiudengjiao
 */
public class Coffee {

	/**
	 * 这里实现了算法中的一个步骤,每个步骤都被实现在分离的方法中
	 */
	void prepareRecipe() {
		builWater();
		brewCoffeeGrinds();
		pourInCup();
		addSugarAndMilk();
	}

	/**
	 * 煮沸水
	 */
	public void builWater() {
		System.out.println("煮沸水");
	}

	/**
	 * 冲泡咖啡
	 */
	public void brewCoffeeGrinds() {
		System.out.println("冲泡咖啡");
	}

	/**
	 * 把咖啡倒进杯子
	 */
	public void pourInCup() {
		System.out.println("把咖啡倒进杯子");
	}

	/**
	 * 加糖和奶
	 */
	public void addSugarAndMilk() {
		System.out.println("加糖和奶");
	}
}

茶类:

/**
 * 茶类
 * 
 * @author qiudengjiao
 */
public class Tea {

	/**
	 * 这里实现了算法中的一个步骤,每个步骤都被实现在分离的方法中
	 */
	void prepareRecipe() {
		builWater();
		steepTeaBag();
		pourInCup();
		addLemon();
	}

	/**
	 * 煮沸水
	 */
	public void builWater() {

	}

	/**
	 * 冲泡茶
	 */
	public void steepTeaBag() {

	}

	/**
	 * 把茶倒进杯子
	 */
	public void pourInCup() {

	}

	/**
	 * 加柠檬
	 */
	public void addLemon() {

	}
}

      从上面我们可以看到,泡茶和咖啡的步骤很像,其中第二和第四步骤不一样,第一和第三步都是一样的,也就是说这里出现了重复代码,发现了重复代码,这是好现象,表示我们需要清理一下设计,在这里,既然茶和咖啡是如此的相似,所以我们应该将共同的部分抽取出来,放进一个基类中。

接下来我们来进行更进一步的设计

1)我们遇到的第一个问题,就是咖啡使用 brewCoffeeGrinds() 和 addSugarAndMilk() 方法,而茶使用 steepTeaBag() 和  addLemon() 方法。

      这里由于第二步和第第四步不太一样,所以我们给他们一个新的名称,不管是泡茶还是泡咖啡我们都用 brew() 这个方法来统一,类似的,加糖和牛奶和加柠檬很相似,都是在饮料中加入调料,我们也给它一个新的方法名称来解决这个问题,就叫做 addCondiments() 吧,这样一来新的 prepareRecipe() 方法就变成了如下的样子:

2)现在我们有了新的 prepareRecipe() 方法

/**
 * 咖啡饮料是一个抽象类
 * 
 * @author qiudengjiao
 */
public abstract class CaffeineBeverage {
	/**
	 * 现在,用同一个 prepareRecipe() 方法类处理茶和咖啡 prepareRecipe() 被声明为
	 * final,因为我们不希望子类覆盖这个方法 我们将步骤二和步骤四泛化成为 brew() 和 addCondiments()
	 */
	final void prepareRecipe() {
		builWater();
		brew();
		pourInCup();
		addCondiments();
	}

	/**
	 * 煮沸水
	 */
	private void builWater() {
		System.out.println("builWater");

	}

	/**
	 * 把饮料倒进杯子
	 */
	private void pourInCup() {
		System.out.println("pourInCup");
	}

	/**
	 * 冲泡方法被声明为抽象,具体操作由子类去实现
	 */
	abstract void brew();

	/**
	 * 加入元素方法被声明为抽象,具体操作由子类去实现
	 */
	abstract void addCondiments();
}

由于写了详细的注释,故不再做多余介绍


3)最后,我们需要处理咖啡和茶类了,这两个类现在都是依赖超类(咖啡因饮料)来处理冲泡法,所以只需要自行处理冲泡和添加调料部分:

咖啡类:

/**
 * 咖啡类
 * 
 * @author qiudengjiao
 */
public class Coffee extends CaffeineBeverage{

	@Override
	void brew() {
		System.out.println("冲泡咖啡");
		
	}

	@Override
	void addCondiments() {
		System.out.println("添加糖和牛奶");
	}	
}

茶类:

/**
 * 茶类
 * 
 * @author qiudengjiao
 */
public class Tea extends CaffeineBeverage {

	@Override
	void brew() {
		System.out.println("冲泡茶");
	}

	@Override
	void addCondiments() {
		System.out.println("添加柠檬");
	}
}


      茶和开咖啡都是继承自咖啡饮料类,只是咖啡喝茶都各自处理了自己不相同的部分,模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现

      接下来我们利用泡茶来追踪一下模板方法是如何工作的,我们会得知在算法内的某些地方,该模板方法控制了算法,让子类能够提供某些步骤的实现...我们开始泡茶:

1)好吧,首先我们需要一个茶对象:

Tea myTea = new Tea();

2)然后我们调用这个模板方法:

myTea.prepareRecipe();

prepareRecipe()方法控制了算法,没有人能够改变它,这个方法也会依赖子类来提供某些或所有步骤的实现。

它会依照算法来制作咖啡因饮料......

3)首先,把水煮沸

boilWater();

这件事情是在咖啡因饮料类(超类)中进行的。

4)接下来,我们需要泡茶,这件事情只有子类才知道要怎么做

brew();

5)现在把茶倒进杯中,所有饮料做法都一样,所以这件事情发生在超类中

pourInCup();

6)最后,我们加进饮料,由于调料是各个饮料独有的,所以由子类来实现它

addCondiments();

总结:由 CaffeineBeverage 类主导一切,它拥有算法,而且保护这个算法,对于子类来说,CaffeineBeverage 类的存在,可以将代码的复用最大化。算法只存在于一个地方,所以容易修改,这个模板方法提供了一个框架,可以让其他的咖啡饮料插件来,新的咖啡因饮料只需要实现自己的方法就可以了,CaffeineBeverage 类专注算法本身,而由子类提供完整的实现。

接下来我们进行代码的总结:

/**
 * 这就是我们的抽象类,他被声明为抽象 用来作为基类,其子类必须实现其操作
 * 
 * @author qiudengjiao
 */

public abstract class AbstractClass {

	/**
	 * 这就是模板方法,它被声明为final,以免子类改变这个算法的顺序
	 */

	final void templateMethod() {
		primitiveOperation1();
		primitiveOperation2();
		concreteOperation();
		hook();
	}

	/**
	 * 这个方法定义成抽象,由具体子类去实现
	 */
	abstract void primitiveOperation1();

	/**
	 * 这个方法定义成抽象,由具体子类去实现
	 */
	abstract void primitiveOperation2();

	/**
	 * 这个具体的方法被定义在抽象类中 将它声明为 final,这样一来子类就无法覆盖它,它可以被模板方法直接调用,或者被子类调用
	 */
	final void concreteOperation() {
		// 这里是实现
	}

	/**
	 * 钩子(这是一个具体的方法,但是什么事情都不做)
	 * 我们也可以有“默认不做事情的方法”,我们称这种方法为钩子,子类可以视情况决定要不要覆盖它们,下面我们会介绍钩子的实际用途
	 */
	public void hook() {

	}
}

三、模板方法中钩子的使用


1)对模板方法进行挂钩

      钩子是一种被声明在抽象类中的方法,但只要有空的或者默认的实现,钩子的存在可以让子类有能力对算法的不同点进行挂钩,要不要挂钩,由子类自行决定,接下来我们来看看钩子的用途。

public abstract class CaffeineBeverageWithHook {

	final void prepareRecipe() {
		builWater();
		brew();
		pourInCup();
		// 这里我们加了一个小小的条件语句,而该条件是否成立,是由具体的方法customerWantsondiments()决定的
		// 如果顾客想要调料,我们才调用addCondiments()
		if (customerWantsondiments()) {
			addCondiments();
		}
	}

	/**
	 * 煮沸水
	 */
	private void builWater() {
		System.out.println("builWater");

	}

	/**
	 * 把饮料倒进杯子
	 */
	private void pourInCup() {
		System.out.println("pourInCup");
	}

	/**
	 * 冲泡方法被声明为抽象,具体操作由子类去实现
	 */
	abstract void brew();

	/**
	 * 加入元素方法被声明为抽象,具体操作由子类去实现
	 */
	abstract void addCondiments();

	/**
	 * 我们在这里定义了一个方法,(通常)是空的缺省实现,这个方法只会返回ture,不做别的事情
	 * 这就是一个钩子,子类可以覆盖这个方法,但不见得一定要这么做
	 * 
	 * @return
	 */
	boolean customerWantsondiments() {
		return true;
	}
}

2)使用钩子

为了使用钩子。我们在子类中覆盖它,在这里钩子控制咖啡因饮料是否执行某部分算法,更明确点就是控制饮料中是否添加调料

带钩子咖啡类:

public class CoffeeWithHook extends CaffeineBeverageWithHook {

	@Override
	void brew() {
		System.out.println("冲泡咖啡");
	}

	@Override
	void addCondiments() {
		System.out.println("添加糖和牛奶");
	}

	public boolean customerWantsondiments() {
		String answer = getUserInput();
		// 让用户输入他们对调料的决定,根据用户的输入返回 true 或 false
		if (answer.toLowerCase().startsWith("y")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 这段代码询问用户是否想要加糖和奶茶,通过命令行获取用户输入
	 * 
	 * @return
	 */
	private String getUserInput() {
		String answer = null;
		System.out.println("Would you like milk and sugar with your cofee(y/n)?");
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		try {
			answer = bf.readLine();
		} catch (IOException ioe) {
			System.err.println("IO error");
		}
		if (answer == null) {
			return "no";
		}
		return answer;
	}
}

带钩子茶类:

public class TeaWithHook extends CaffeineBeverageWithHook {

	@Override
	void brew() {
		System.out.println("冲泡茶");
	}

	@Override
	void addCondiments() {
		System.out.println("添加柠檬");
	}

	/**
	 * 覆盖了这个钩子,提供了自己的功能
	 */
	public boolean customerWantsondiments() {
		String answer = getUserInput();
		// 让用户输入他们对调料的决定,根据用户的输入返回 true 或 false
		if (answer.toLowerCase().startsWith("y")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 这段代码询问用户是否想要加糖和奶茶,通过命令行获取用户输入
	 * 
	 * @return
	 */
	private String getUserInput() {
		String answer = null;
		System.out.println("Would you like milk and sugar with your cofee(y/n)?");
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		try {
			answer = bf.readLine();
		} catch (IOException ioe) {
			System.err.println("IO error");
		}
		if (answer == null) {
			return "no";
		}
		return answer;
	}
}


3)执行测试程序

public class BeverageTest {
	public static void main(String[] args){
		//创建一杯茶
		TeaWithHook teaHook = new TeaWithHook();
		//创建一杯咖啡
		CoffeeWithHook coffeeHook = new CoffeeWithHook();
		
		System.out.println("\nMaking tea...");
		teaHook.prepareRecipe();
		System.out.println("\nMaking coffee...");
		coffeeHook.prepareRecipe();
	}
}

4)执行结果

让茶中添加柠檬,咖啡中不添加:


让咖啡中添加糖和牛奶,茶中不添加:



四、模板方法在 Android 中的应用

      模板方法在Android中有很广泛的应用,Activity和Fragment生命周期方法的回调,AsyncTask异步框架的设计等都使用了模板方法模式,这里我们不展开看代码,大家有兴趣可以自行去阅读

今天就写到这里,如有错误请指出


本地部署gradle 在部署CAS构建执行包时,如果按照CAS的官方命令gradlew clean build,如果系统没安装过gradle,这个步骤将会从网上下载gradle,但是进度非常慢,耗时很长。为了更快地完成项目构建,我们可以直接在本地部署好gradle,节省一点时间。 阅读详情

相关推荐

SVM-支持向量机学习(1):线性可分SVM的基本型

1. foreword先看的是李航老师的书第7章,比较传统按照以下三节展开: 线性可分SVM 线性SVM 非线性SVM SMO算法 李航老师讲东西向来不拖泥带水,但本节也几乎用了40页的篇幅,足见涉及内容之多。7月底硬着头皮啃了下来,边看边在笔记上摘抄标注,花了2天时间对SVM有了基本认识。一个月过去了,如今重新整理为博客,再看轻松许多,并不断对比西瓜书的内容,启望达到融会贯通。西瓜书此节明显节奏轻

鸟恋旧林的博客 8680

模版模式

标签: 设计模式 引言 在模板方法模式中,将实现功能的每一个步骤所对应的方法称为基本方法(例如“点单”、“吃东西”和“买单”),而调用这些基本方法同时定义基本方法的执行次序的方法称为模板方法(例如“请客”)。模板方法定义算法执行的骨架,子类继承下来直接使用,一般用final修饰不允许子类修改。 抽象类的任务是搭建逻辑的框架,通常由经验丰富的人员编写,抽象类的好坏直接决定了程序是否稳定。...

diaoyang7352的博客 209

GitHub 新手使用手册

理论说太多容易忘,来实践实践吧。

2501_90226046的博客 1053

设计模式(十):模板方法模式

1、整体框架 2、介绍 2.1、定义 模版方法模式:定义一个模版结构即抽象,将具体内容延迟到子类去实现 2.2、作用 模版方法模式是基于继承的。在不改变模版结构的前提下,在子类中重新定义模版中的内容。 2.3、解决的问题 提高代码的复用性:将相同部分的代码放在抽象类的父类中,而将不同的代码放到不同的子类中。 实现反向控制:通过父类调用子类的操作,并通过子类的具体实现扩展不同的行为,实现反向控制。 3、认识模版方法模式 3.1、变与不变 程序设计的一个很重要的思考点就是“变与不变...

mingyuli的博客 1799

ESP32-C61 eFuse控制器深度解析:寄存器架构与安全烧写实践

eFuse(电子熔丝)是嵌入式芯片实现硬件级不可逆配置与信任根构建的核心物理机制,其本质是通过电学编程固化关键安全参数。原理上依赖熔丝单元的单向导通/断开特性,结合Reed-Solomon纠错、多级写保护和时序可控编程,保障数据在宽温域与工艺偏差下的高可靠性。技术价值在于为Secure Boot、Flash加密、密钥隔离等安全功能提供可信锚点,支撑从启动到运行的全链路防护。典型应用场景涵盖物联网设备量产烧录、安全启动使能、MAC地址固化及抗DPA密码运算配置。本文聚焦ESP32-C61平台,深入解析其eFu

weixin_42589700的博客 123

国产AI芯片实战:用寒武纪MLU370低成本部署DeepSeek-R1,实测推理效果与成本分析

本文详细介绍了寒武纪MLU370芯片在部署DeepSeek-R1大模型时的实战效果与成本优势。通过实测数据对比,MLU370在推理速度、能效比和本地化服务方面表现突出,尤其适合智能客服、内容生成等场景,可显著降低硬件投入和运维成本。

weixin_30613727的博客 457

设计模式-模板方法模式(Template Method)

模板方法模式,也被称为模板模式,是一种行为型设计模式。它在一个抽象类中公开定义了执行其方法的模板,规定了算法的骨架。其主要特点是将一些步骤延迟到子类中,这些子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式主要解决了一些通用的方法在每一个子类都重新写了这一问题,其主要目的是将这些通用算法抽象出来。通过使用模板方法模式,子类可以在不改变算法结构的情况下,重新定义算法中的某些特定步骤。

miaoyl的博客 3195

IT资产管理(三)之GLPI资产录入

glpi 在 10 版本之后已经有自带的 glpi-agent 代理程序可自动获取服务器、电脑等的信息并进行自动录入和更新,不再依赖 10 版本之前的 fusioninventory 插件或者第三方资产统计平台 OCS Inventory 等

予挚之的博客 2986

设计模式-模板方法模式-Template Method Pattern

首先,我们定义一个模板基类,其中包含模板方法和一些虚函数,这些虚函数将在派生类中被重写。// 模板基类public:// 模板方法step1();step2();step3();protected:// 抽象步骤,子类必须实现创建一个抽象基类,它定义了模板方法和算法的框架。模板方法:一个或多个步骤组成的算法,这些步骤通过调用抽象操作来执行。抽象操作:定义为纯虚函数(pure virtual functions),子类必须实现这些函数。

wesigj的博客 1292

TC3xx芯片中断配置避坑指南:从AUTOSAR Davinci配置到SRN地址计算的完整流程

本文详细解析了英飞凌TC3xx芯片的中断配置流程,从AUTOSAR Davinci工具链到硬件调试的全链路指南。重点介绍了中断路由(IR)模块、服务请求节点(SRN)和中断控制单元(ICU)的配置技巧,帮助开发者避开常见陷阱,优化中断性能。

weixin_30628801的博客 413

5ZCM6ZGrVDllSFLkv6Hmga/ljJbnrqHnkIbns7vnu58= GetFlowDropDown SQL注入

5ZCM6ZGrVDllSFLkv6Hmga/ljJbnrqHnkIbns7vnu58=、eHR/OA一体化智慧云平台、智慧一卡通云平台、行业软件开发与定制、智慧企业管理信息化咨询与项目服务为核心业务的顾问式管理咨询和软件个性定制开发的高科技股份集团公司。同鑫T9eHR信息华管理系统存在SQL注入漏洞,攻击者可通过该漏洞上传shell。关闭互联网暴露面或接口设置访问权限。利用sqlmap进行shell。

iSee857的博客 701

【设计模式】——模板方法模式(Template Method Pattern)

模板方法模式通过定义一个算法的骨架,允许子类在不改变算法结构的前提下,通过重写某些步骤的具体实现来定制算法的行为。这种模式提高了代码的复用性和可维护性,使得算法的结构更加清晰,同时也便于扩展和维护。在C++中,模板方法模式是一种非常实用的设计模式,通过它我们可以构建出灵活且易于扩展的软件系统。

J^T的博客 1037

某智能物流无人值守系统 ExportReport SQL注入漏洞复现

某智能物流无人值守系统 ExportReport存在SQL注入漏洞,未经身份验证的远程攻击者除了可以利用 SQL 注入漏洞获取数据库中的信息(例如,管理员后台密码、站点的用户个人信息)之外,甚至在高权限的情况可向服务器中写入木马,进一步获取服务器系统权限。

0xSec 818

23种设计模式之模板方法模式(Template Method Pattern)

假设我们要实现一个对一个数组进行排序的程序,我们可以定义一个抽象类 ArraySorter,其中包含一个模板方法 sort,这个方法包含以下步骤:检查数组是否为空、确定排序算法、调用具体的排序算法。在模板方法模式中,我们通常会定义一个抽象类,它包含了一个模板方法和一些抽象方法,这些抽象方法通常由子类来实现。这样,就可以将算法的公共部分放在抽象类中实现,避免了大量的重复代码,并且能够根据需要灵活地选择不同的排序算法。💕欢迎大家:这里是优快云,我总结知识的地方,欢迎来到我的博客,我亲爱的大佬😘。

小威的博客 1万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Java设计模式——模板方法模式【Template Method Pattern】

Java设计模式、模板方法模式、Template Method Pattern

scorpio的博客 3万+

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

设计模式教程:模板方法模式(Template Method Pattern)

定义一个操作中的算法骨架,将一些步骤延迟到子类中实现。通过模板方法,子类可以重新定义算法中的某些步骤,而无需改变算法的结构。

遇见伯灵说的博客 1379

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

设计模式 -- 模板方法模式(Template Method Pattern)

定义一个操作的算法框架,而将具体实现延迟到子类中进行,使得子类在不改变整体算法框架的基础上,可以自定义算法实现。 应用场景 多个子类有公有的方法,并且逻辑基本相同时。 重要复杂的算法可以把核心算法设计为模板方法,具体细节则由子类实现 重构代码时,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。 ① 模板方法:定义了算法的骨架,按某种顺序调用其包

魔法师之家 897

23种设计模式——模板方法模式(Template Method Pattern)详解

本文介绍23种经典设计模式之——模板方法模式(Template Method Pattern)的介绍及使用

Meteors.的博客 826

设计模式(十四)——模板方法模式(Template Method Pattern)

模板方法模式(Template Method Pattern) 基本介绍 模板方法模式是编程中经常用得到模式。它定义了一个操作中的算法骨架,将某些步骤延迟到子类中实现。这样,新的子类可以在不改变一个算法结构的前提下重新定义该算法的某些特定步骤。 核心 处理某个流程的代码已经都具备,但是其中某个节点的代码暂时不能确定。因此,我们采用模板方法模式,将这个节点的代码实现转移给子类完成。即:处理步骤父类中...

Duktig的博客 359

Java设计模式 二十 模板方法模式 (Template Method Pattern)

模板方法模式通过定义算法的框架,将部分步骤的实现推迟到子类,使得子类能够在不改变算法结构的前提下,定制某些具体步骤。它是一个非常适用于处理具有固定执行顺序的算法的设计模式。模板方法模式提高了代码复用性和扩展性,但同时也带来了继承关系的复杂化,需要在合理的场景下使用。

空 979

设计模式精讲 Day 22:模板方法模式(Template Method Pattern)

模板方法模式(Template Method Pattern)是一种行为型设计模式,它定义了一个算法的框架,并在该框架中调用一些抽象方法或钩子方法,由子类来实现这些方法。这样,算法的结构保持不变,但具体的实现可以由不同的子类进行定制。模板方法模式的核心思想是将算法的骨架定义在父类中,将具体步骤延迟到子类中实现。通过模板方法,可以统一算法的执行流程,同时允许子类灵活调整部分步骤。模板方法模式适用于具有固定流程但部分步骤需定制的场景。通过完整 Java 示例,展示了模板方法模式的实现方式和实际应用。

在未来等你的专栏 1396

设计模式-20模板方法模式Template Method Pattern

模板方法模式是一种行为设计模式,它定义算法框架,将可变步骤延迟到子类实现。该模式通过抽象类定义算法骨架(模板方法),其中包含固定步骤和抽象/钩子方法。子类重写这些方法以改变特定步骤,而不修改算法结构。适用于有相同流程但部分步骤不同的场景,如数据处理、文档生成等。优点包括避免代码重复、提高复用性、便于扩展,但可能增加系统复杂度。典型实现包含抽象类定义模板方法和步骤,具体子类实现可变部分。

d3y1`5 81_09 815

设计模式中的模板方法模式(Template Method Pattern)

在软件开发中,经常会遇到多个类具有相似的逻辑流程,但其中某些步骤可能有所不同。例如,数据处理流程、游戏 AI 决策、网页渲染、文档格式转换等。如果在每个子类中都重复实现相似的逻辑,不仅**代码冗余**,而且**难以维护**。**模板方法模式(Template Method Pattern)** 提供了一种**定义算法骨架,并允许子类实现特定步骤的方法,从而实现代码复用、行为可扩展的设计。本文将详细介绍模板方法模式的概念、应用场景,并通过 Python 代码示例展示其实现方式。

970

JAVA设计模式之 模板方法模式【Template Method Pattern】

一、概述 二、适用chuangk

小吕丶Code阶区 3480

Java设计模式之模板方法模式(Template Method Pattern)

假设需要实现制作茶和咖啡的流程,两者步骤类似(烧水、冲泡、倒入杯子),但具体冲泡方法和添加调料不同。:框架定义通用流程,允许用户自定义部分步骤(如Servlet生命周期、JUnit测试流程)。:当多个类有相似的流程,但某些步骤实现不同时(如数据处理流程、文件解析流程)。:适用于具有固定流程但部分步骤需要定制的场景,如框架扩展、多态流程处理。,用于定义算法的骨架,将某些步骤的具体实现延迟到子类中。:通过父类定义算法流程,子类灵活实现具体步骤,实现代码复用和流程控制。方法为模板方法,由框架调用。

guanxin0206的博客 672
上一篇: 设计模式之装饰者模式
下一篇: Android ViewGroup 中 addView 方法使用详解
QDJdeveloper
博客等级 码龄11年 108粉丝 49原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值