模板方法
时间:2019-11-20
本文章向大家介绍模板方法,主要包括模板方法使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
- 概述
- UML类图
- 代码栗子
- Spring源码体现
- 总结
概述
概述
模板方法是一种行为设计模式,它在超类(抽象类)中定义算法的框架,但允许子类覆盖算法的特定步骤而无需更改其结构。作用
- 允许子类实现变化的行为(通过重写钩子方法)
- 避免了重复代码:算法的一般工作流程在抽象类的模板方法中实现一次,而子类中实现必要的变体。
- 控制允许专业化的点。如果子类只是简单地覆盖模板方法,则它们可以对工作流进行根本性和任意的更改。相反,通过仅覆盖钩子方法,仅可以更改工作流的某些特定细节,并且整个工作流保持不变。
UML类图
代码栗子
//动作类
public interface Action {
/**
* 吃
* @param name
*/
void eat(String name) ;
}
//抽象模板类
public abstract class AbstractDefaultAction implements Action {
/**
* 吃饭前的动作
* 子类必须实现的方法
*/
public abstract void before();
//模板方法
@Override
public final void eat(String name) {
before();
System.out.println("吃饭吃的是:"+name);;
after();
}
/**
* 吃饭后的动作
* 钩子方法
*/
public void after(){
System.out.println("默认实现,洗手");
}
}
public class LiSi extends AbstractDefaultAction {
private static String name ="李四";
@Override
public void before() {
System.out.println(name+";吃饭前,不洗手");
}
@Override
public void after() {
System.out.println("吃完洗碗");
}
}
public class ZhangSan extends AbstractDefaultAction {
private static String name ="张三";
@Override
public void before() {
System.out.println(name+";吃饭前,洗手");
}
}
- client
public class Main {
public static void main(String[] args) {
Action a = new ZhangSan() ;
a.eat("香蕉");
System.out.println("-----------分割线---------");
Action b = new LiSi() ;
b.eat("苹果");
}
}
- 运行效果
Spring源码体现
使用IDEA 双击shift查找类,进入org.springframework.context.ConfigurableApplicationContext,找到refresh() 方法,找到他的实现类org.springframework.context.support.AbstractApplicationContext,它的实现方式就是一个模板方法,源码如下:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
根据这个refresh的方法注释可知,这就是Spring加载资源配置文件用的,规定了整个加载流程,但是放开了流程细节交由其子类实现
总结
- 多个子类有公有的方法,并且逻辑基本相同时。把核心算法设计为模板方法,周边的相关细节功能则由各个子类实现。
- 重构时,把相同的代码抽取到父类中,然后通过钩子函数约束其行为。
原文地址:https://www.cnblogs.com/tanoak/p/11897851.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法