前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >模板模式

模板模式

作者头像
@派大星
发布2023-06-28 14:17:13
1190
发布2023-06-28 14:17:13
举报
文章被收录于专栏:码上遇见你


无场景,不设计,有这样的一个需求:有一个小贩需要制作豆浆,制作豆浆的流程如下:

  1. 制作豆浆的流程 选材--->添加配料--->浸泡--->放到豆浆机打碎
  2. 通过添加不同的配料,可以制作出不同口味的豆浆
  3. 选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的

请使用 模板方法模式 完成 废话不多说,直接步入正题。

模板方法模式

基本概念

  1. 模板方法模式(Template Method Pattern)又叫模板模式(Template Pattern),在一个抽象类中公开定义了执行它的方法的模板,它的子类可以按需重写方法实现,但调用将以抽象类中的定义方式进行
  2. 简单来说:模板方法模式定义了一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法结构,就可以重新定义该算法的某些特定步骤
  3. 模板方法模式属于行为型模式

模板方法模式类图

说明

  • AbstractClass 抽象类,类中实现了模板方法,定义了算法的骨架,具体的子类需要去实现其他的抽象方法operation2,3,4
  • ConcreteClass 实现抽象方法operation2,3,4 以完成算法中特点子类的步骤

好了接下来使用应用案例来进行理解一下吧。

豆浆制作应用实例要求

说明如下:

  • 制作豆浆的流程 选材--->添加配料--->浸泡--->放到豆浆机打碎
  • 通过添加不同的配料,可以制作出不同口味的豆浆
  • 选材、浸泡和放到豆浆机打碎这几个步骤对于制作每种口味的豆浆都是一样的(红豆、花生豆浆)

类图

代码演示

  • SoyaMilk(抽象类,表示豆浆)
代码语言:javascript
复制
public abstract class SoyaMilk {

	//模板方法, make , 模板方法可以做成final , 不让子类去覆盖.
	final void make() {
		
		select(); 
		addCondiments();
		soak();
		beat();
		
	}
	
	//选材料
	void select() {
		System.out.println("第一步:选择好的新鲜黄豆  ");
	}
	
	//添加不同的配料, 抽象方法, 子类具体实现
	abstract void addCondiments();
	
	//浸泡
	void soak() {
		System.out.println("第三步, 黄豆和配料开始浸泡, 需要3小时 ");
	}
	 
	void beat() {
		System.out.println("第四步:黄豆和配料放到豆浆机去打碎  ");
	}
}
  • RedBeanSoyaMilk(红豆豆浆)
代码语言:javascript
复制
public class RedBeanSoyaMilk extends SoyaMilk {

	@Override
	void addCondiments() {
		// TODO Auto-generated method stub
		System.out.println(" 加入上好的红豆 ");
	}

}
  • PeanutSoyaMilk(花生豆浆)
代码语言:javascript
复制
public class PeanutSoyaMilk extends SoyaMilk {

	@Override
	void addCondiments() {
		// TODO Auto-generated method stub
		System.out.println(" 加入上好的花生 ");
	}

}
  • Client(调用)
代码语言:javascript
复制
public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//制作红豆豆浆
		
		System.out.println("----制作红豆豆浆----");
		SoyaMilk redBeanSoyaMilk = new RedBeanSoyaMilk();
		redBeanSoyaMilk.make();
		
		System.out.println("----制作花生豆浆----");
		SoyaMilk peanutSoyaMilk = new PeanutSoyaMilk();
		peanutSoyaMilk.make();
	}

}

模板方法模式的钩子方法

模板方法模式的钩子方法

  1. 在模板方法模式的父类中,我们可以定义一个方法,它默认不做任何事,子类可以视情况要不要覆盖它,该方法称为“钩子”。
  2. 还是用上面做豆浆的例子来讲解,比如,我们还希望制作纯豆浆,不添加任何的配料,请使用钩子方法对前面的模板方法进行改造

代码演示

  • SoyaMilk
代码语言:javascript
复制
//抽象类,表示豆浆
public abstract class SoyaMilk {

	//模板方法, make , 模板方法可以做成final , 不让子类去覆盖.
	final void make() {
		
		select(); 
		if(customerWantCondiments()) {
			addCondiments();
		}
		soak();
		beat();
		
	}
	
	//选材料
	void select() {
		System.out.println("第一步:选择好的新鲜黄豆  ");
	}
	
	//添加不同的配料, 抽象方法, 子类具体实现
	abstract void addCondiments();
	
	//浸泡
	void soak() {
		System.out.println("第三步, 黄豆和配料开始浸泡, 需要3小时 ");
	}
	 
	void beat() {
		System.out.println("第四步:黄豆和配料放到豆浆机去打碎  ");
	}
	
	//钩子方法,决定是否需要添加配料
	boolean customerWantCondiments() {
		return true;
	}
}
  • PureSoyaMilk(纯豆浆)
代码语言:javascript
复制
public class PureSoyaMilk extends SoyaMilk{

	@Override
	void addCondiments() {
		// TODO Auto-generated method stub
		//空实现
	}
	
	@Override
	boolean customerWantCondiments() {
		// TODO Auto-generated method stub
		return false;
	}
 
}

(红豆豆浆)和(花生豆浆)不变

  • Client
代码语言:javascript
复制
public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("----制作纯豆浆----");
		SoyaMilk pureSoyaMilk = new PureSoyaMilk();
		pureSoyaMilk.make();
	}

}

以上就是模板方法模式的基本概念以及应用案例的展示,不知道是否对模板方法模式有更好的一个理解。接下来给大家讲解一下模板方法模式在Spring源码中的应用。


模板方法模式在Spring框架应用的源码分析

Spring IOC容器初始化时运用到的模板方法模式

代码分析

  • 首先我们先查看ConfigurableApplicationContext这个类,它里面有一个非常重要的方法Refresh方法,这是一个抽象的方法,
  • 我们看到 它有一个子类AbstractApplicationContext
  • AbstractApplicationContext这个类里面就有refresh()方法

由此可见refresh()就是一个模板方法

  • AbstractApplicationContext这个类中的refresh()方法中还有一个obtainFreshBeanFactory()方法。
  • 我们继续追这个obtainFreshBeanFactory()方法发现里面有refreshBeanFactory()getBeanFactory()这两个方法,
  • 我们点击refreshBeanFactory()``getBeanFactory()这两个方法发现它们是当前类的抽象方法(会被它的子类去实现)
  • AbstractApplicationContext 的子类 这里就不一一查看了
  • 但是在子类GenericApplicationContext中有实现 refreshBeanFactory()``getBeanFactory()这两个方法

我们继续查看Refresh()方法是否有钩子方法

  • 然后 我们查看其中的postProcessBeanFactory()方法,发现这是一个``空方法`。它的意义就是让子类覆盖它,确定其就是一个钩子方法
  • onRefresh()也是一个钩子方法

说了这么多不知是不是有点蒙呢。用图形总结一下吧:


本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上遇见你 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 模板方法模式
    • 基本概念
      • 模板方法模式类图
        • 模板方法模式的钩子方法
          • 模板方法模式的钩子方法
          • 代码演示
        • 模板方法模式在Spring框架应用的源码分析
          • 代码分析
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档