【设计模式】【行为型模式】模板模式
概念
模板模式定义了一个算法的步骤,并允许子类为一个或多个步骤提供其实践方式。让子类在不改变算法架构的情况下,重新定义算法中的某些步骤。
抽象摸板角色:(抽象父类)
- 定义了一个或多个抽象操作,以便让子类实现
- 定义并实现了一个摸板方法
具体摸板角色:(具体实现类)
- 实现父类所定义的一个或多个抽象方法
- 每一个抽象摸板角色都可以有任意多个具体摸板角色与之对应
- 每一个具体摸板角色都可以给出这些抽象方法的不同实现
模板方法模式就是基于继承的代码复用技术的。在模板方法模式中,我们可以将相同部分的代码放在父类中,而将不同的代码放入不同的子类中。也就是说我们需要声明一个抽象的父类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法让子类来实现剩余的逻辑,不同的子类可以以不同的方式来实现这些逻辑。所以模板方法的模板其实就是一个普通的方法,只不过这个方法是将算法实现的步骤封装起来的。
模式中的方法种类:
- 抽象模板角色里提供完整的方法,它完成了所有派生类都要用到的一些基本功能。
- 抽象模板角色里只提供空方法,把功能全部留给派生类去实现。
- 抽象模板角色里只包含某些操作的默认实现,派生类里可以重新定义这些方法的实现。
- 抽象模板角色里模板方法,他是一个调用抽象方法,钩子方法以及具体方法的各种组合。
实例
创建一个定义操作的 Game 抽象类,其中,模板方法设置为 final,这样它就不会被重写。Cricket 和 Football 是扩展了 Game 的实体类,它们重写了抽象类的方法。
TemplatePatternDemo,我们的演示类使用 Game 来演示模板模式的用法。
步骤 1
创建一个抽象类,它的模板方法被设置为 final。
Game.javapublic abstract class Game {abstract void initialize();abstract void startPlay();abstract void endPlay();//模板public final void play(){//初始化游戏initialize();//开始游戏startPlay();//结束游戏endPlay();}
}
步骤 2
创建扩展了上述类的实体类。
Cricket.javapublic class Cricket extends Game {@Overridevoid endPlay() {System.out.println("Cricket Game Finished!");}@Overridevoid initialize() {System.out.println("Cricket Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Cricket Game Started. Enjoy the game!");}
}
Football.javapublic class Football extends Game {@Overridevoid endPlay() {System.out.println("Football Game Finished!");}@Overridevoid initialize() {System.out.println("Football Game Initialized! Start playing.");}@Overridevoid startPlay() {System.out.println("Football Game Started. Enjoy the game!");}
}
步骤 3
使用 Game 的模板方法 play() 来演示游戏的定义方式。
TemplatePatternDemo.javapublic class TemplatePatternDemo {public static void main(String[] args) {Game game = new Cricket();game.play();System.out.println();game = new Football();game.play(); }
}
步骤 4
验证输出。
Cricket Game Initialized! Start playing.
Cricket Game Started. Enjoy the game!
Cricket Game Finished!Football Game Initialized! Start playing.
Football Game Started. Enjoy the game!
Football Game Finished!
应用
在Spring中的AbstractApplicationContext的refresh方法中使用了模板模式。
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) {// Destroy already created singletons to avoid dangling resources.beanFactory.destroySingletons();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}}}
AbstractApplicationContext类中的refresh定义好了代码逻辑骨架,obtainFreshBeanFactory()方法中调用了refreshBeanFactory();
,该方法在AbstractApplicationContext中是抽象方法,需要在子类中具体实现。
//AbstractApplicationContextprotected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isInfoEnabled()) {logger.info("Bean factory for application context [" + getId() + "]: " +ObjectUtils.identityToString(beanFactory));}if (logger.isDebugEnabled()) {logger.debug(beanFactory.getBeanDefinitionCount() + " beans defined in " + this);}return beanFactory;}protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
查看AbstractApplicationContext的子类
最终类是FileSystemXmlApplicationContext,方法的具体实现在AbstractRefreshableApplicationContext中可以找到。
//AbstractRefreshableApplicationContextprotected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) {destroyBeans();closeBeanFactory();}try {DefaultListableBeanFactory beanFactory = createBeanFactory();customizeBeanFactory(beanFactory);loadBeanDefinitions(beanFactory);synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing XML document for application context [" + getDisplayName() + "]", ex);}}
参考资料:
模板模式
使用模板方法设计模式、策略模式 处理DAO中的增删改查
设计模式总结
转载于:https://www.cnblogs.com/z00377750/p/9396187.html
【设计模式】【行为型模式】模板模式相关推荐
- 设计模式(创建型)之建造者模式(Builder Pattern)
PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbob ...
- 设计模式之策略模式+工厂模式+模板模式结合
设计模式之策略模式+模板模式 为什么总是学不好设计模式 从"登录功能"中发现问题. 首先我们简单的了解功能需求: 于是你开始干活了: 1.控制层代码如下,根据不同的登录方式调用不同 ...
- Java设计模式之策略模式+工厂模式+模板模式
Java设计模式之策略模式+工厂模式+模板模式 1.策略模式+工厂模式+模板模式 个人的理解:实际开发工程中,一些业务很复杂的逻辑使用很多的 if 或者 if···else 语句,不利于维护和扩展,为 ...
- 设计模式-05.01-行为型-观察者模板模式
文章目录 观察者模式[常用] Demo案例-天气预报 方案一 WeatherData CurrentConditions Client 问题分析 观察者模式方案 Subject[接口] Observe ...
- 【设计模式】【行为型】模板模式之模拟去商场购物
一.概念 1.1 概念 在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板.它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行.这种类型的设计 ...
- 【设计模式系列】行为型之模板模式
目录 理论 实践 总结 理论 1.模板模式:定义一个操作算法中的框架,而将这些步骤延迟加载到子类中. 模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤: 2.角色: 抽象模板 ...
- 常用设计模式-策略模式+工厂模式+模板模式(使用场景、解决方案)
在策略模式+工厂模式中,没有使用到模板模式,因为张三和李四的业务逻辑都是调用AAA方法,如果现在在增加一个方法,次方法只需要李四一人去实现BBB方法,此时张三的handel中就会报错,需要张三也去实现 ...
- 第十三章行为型模式—模板模式
文章目录 模板模式 解决的问题 结构 实例 存在的问题 适用场景 JDK源码 - InputStream 行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对 ...
- 行为模式(模板模式命令模式备忘录模式)
目录 模板方法模式(Template) 介绍 实现 命令模式(Command) 介绍 实现 备忘录模式(Memento) 介绍 实现 模板方法模式(Template) 一个抽象类公开定义了执行它的方法 ...
- 模板方法模式(模板模式)——钩子方法
豆浆制作问题 编写制作豆浆的程序,说明如下: 制作豆浆的流程选材->添加配料->浸泡->放到豆浆机打碎 通过添加不同的配料,可以制作出不同口味的豆浆 选材.浸泡和放到豆浆机打碎这几个 ...
最新文章
- python3 异步错误 asyncio.Semaphore RuntimeError: Task got Future attached to a different loop
- 多选取值_R语言缺失值的处理——回归预测法
- java搭建maven项目_Eclipse使用maven创建Java Web项目完整示例
- 中国科技大学校长朱清时:我的两次“错误”选择
- 硕博士的朋友圈都有哪些特点?
- 查一个字段中字符集超过30的列_详细解读MySQL的30条军规
- 洛谷P3382 【模板】三分法
- 微服务的4个设计原则和19个解决方案
- Oracle创建上下文 SYS_CONTEXT
- layui 主动验证表单规则
- 汇编指令大全(带注释)
- 别人的底鼓/808为什么比你有力?你可能忘了用这个插件
- Linux之查看物理主机的CPU温度
- No certificate for team ‘‘ matching ‘iPhone Distribution: VOVA TECH LIMITED ()‘ Select a different s
- 网络安全——Webshell管理工具
- 【数据挖掘结果】大数据企业的汇总信息
- 苹果电脑python快捷键_我常用用的MAC快捷键和手势
- 通行时间可调的两路口交通灯设计实验(基于Multisim仿真)
- Android平台安全分析
- 来看看国外DBA的工资
热门文章
- hadoop+hive+flink+hbase交互的版本兼容性
- numpy中的clip函數的用法
- 进度条tqdm基本用法
- ubuntu下面的背光键盘的使用
- 主体ubuntu16.04,宿体virtualbox下的windows7的共享文件夹设置
- springboot----静态页面templates文件访问
- php报表服务器配置,服务器_SQL Server 2008升级报表服务器数据库,报表服务器数据库可以为一个 - phpStudy...
- vi/vim的基本使用方法
- Android Unable to resolve target 'android-8'
- 远程连接MySql数据库