设计模式之模版模式
# 设计模式之模版模式
# 一、简介
定义了一个操作中算法的骨架,将一些步骤延迟到子类中
注意事项:为防止恶意操作,一般会在模板方法上增加 final 关键词。
# 二、实现方式
抽象模版类 一个抽象类,它的模板方法被设置为 final
public abstract class Game { abstract void initialize(); abstract void startPlay(); abstract void endPlay(); //模板 public final void play(){ //初始化游戏 initialize(); //开始游戏 startPlay(); //结束游戏 endPlay(); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14具体实现类
public class Cricket extends Game { @Override void endPlay() { System.out.println("Cricket Game Finished!"); } @Override void initialize() { System.out.println("Cricket Game Initialized! Start playing."); } @Override void startPlay() { System.out.println("Cricket Game Started. Enjoy the game!"); } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14测试
public class TemplatePatternDemo { public static void main(String[] args) { Game game = new Cricket(); game.play(); } }
1
2
3
4
5
6
# 三、应用场景
# 1、Spring容器中的模版模式:上下文对象AbstractApplicationContext
AbstractApplicationContext
的refresh()
方法就是一个模版方法,它定义了整个容器加载初始化的框架,其中postProcessBeanFactory(beanFactory)
和onRefresh()
方法的具体实现在子类中
@Override
public void refresh() throws BeansException, IllegalStateException {
...
...
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);//模版模式1,具体实现在子类中
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
...
...
// Initialize event multicaster for this context.
//初始化事件多播器,管理所有的监听器,负责调用事件对应的监听器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();//模版模式2,具体实现在子类中
// Check for listener beans and register them.
// 将事件监听器注册到多播器上
registerListeners();
...
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 2、Spring-jdbc模块中的模板模式:JdbcTemplate
JdbcTemplate
是模版模式和命令模式的结合,将需要扩展的方法以命令的形式作为参数传入JdbcTemplate
的execute
方法中,通过回调方法的方式来进行调用
@Nullable
private <T> T execute(StatementCallback<T> action, boolean closeResources) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
Connection con = DataSourceUtils.getConnection(obtainDataSource());
Statement stmt = null;
try {
stmt = con.createStatement();
applyStatementSettings(stmt);
T result = action.doInStatement(stmt);
handleWarnings(stmt);
return result;
}
catch (SQLException ex) {
...
}
finally {
...
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20