一篇博客读懂设计模式之---模板方法模式
設計模式之模板方法模式:
定義一個操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
簡而言之就是:父類定義了骨架(調用哪些方法及其順序),某些特定的方法由具體的子類來實現(xiàn)。
所以呢?在父類模板方法中是有兩類方法的:
1). 抽象方法:父類是抽象方法,子類必須實現(xiàn)的,如下面的startGame,endGame方法;
2). 鉤子方法:父類中是一個空方法,子類繼承的時候默認也是空的,這個方法有什么用呢?子類可以通過這個方法來自定義自己的其他一些步驟和過程,從而達到控制父類的目的。
我們將創(chuàng)建一個定義操作的 Game 抽象類,其中,模板方法設置為 final,這樣它就不會被重寫。BasketballGame和 FootballGame 是擴展了 Game 的實體類,它們重寫了抽象類的方法。
1. 創(chuàng)建抽象類Game:
public abstract class Game {abstract void startGame();abstract void endGame();abstract void init();final void play(){init();startGame();endGame();} }2. 創(chuàng)建擴展了上述類的實體類:
public class FootballGame extends Game {@Overridevoid startGame() {System.out.println("start football");}@Overridevoid endGame() {System.out.println("end football");}@Overridevoid init() {System.out.println("init football");} } public class BasketballGame extends Game {@Overridevoid startGame() {System.out.println("start basketball");}@Overridevoid endGame() {System.out.println("end basketball");}@Overridevoid init() {System.out.println("init basketball");} }3. 使用測試類測試:
public class TemplMain {public static void main(String[] args) {Game game = new FootballGame();//這樣如果你想要改變其他球類,只需要換成下面這種形式,其他不用改變//Game game = new BasketballGame();game.play();} }再升級一下,舉另一個例子:
接口描述的是一種共性,一種動作action;
抽象類描述的是一個模板,一個特定的過程;
而子類則是可以根據(jù)自己的需要定制自己的過程。
不過,這樣做的好處又是什么呢?
其實我們在一些框架,如spring,mybatis等都可以看到模板方法模式的影子,下面簡單舉一下例子:
像mybatis的Executor接口:
你就可以很明顯的看到這種模式:
spring中的模板方法模式:
spring模板方法我來摘抄一些重點給大家看看:
下面的代碼展示了Spring IOC容器初始化時運用到的模板方法模式。(截取部分關鍵代碼)
1、首先定義一個接口ConfigurableApplicationContext,聲明模板方法refresh
2、抽象類AbstractApplicationContext實現(xiàn)了接口,主要實現(xiàn)了模板方法refresh(這個方法很重要,是各種IOC容器初始化的入口)的邏輯:
public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext, DisposableBean {/**模板方法的具體實現(xiàn)*/public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();//注意這個方法是,里面調用了兩個抽象方法refreshBeanFactory、getBeanFactory// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {//注意這個方法是鉤子方法,點進去父類看可以發(fā)現(xiàn)是空的// 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.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}}} }這里最主要有一個抽象方法obtainFreshBeanFactory、兩個鉤子方法postProcessBeanFactory和onRefresh,看看他們在類中的定義
看看獲取Spring容器的抽象方法:
3、具體實現(xiàn)的子類,實現(xiàn)了抽象方法getBeanFactory的子類有:
AbstractRefreshableApplicationContext:
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {@Overridepublic final ConfigurableListableBeanFactory getBeanFactory() {synchronized (this.beanFactoryMonitor) {if (this.beanFactory == null) {throw new IllegalStateException("BeanFactory not initialized or already closed - " +"call 'refresh' before accessing beans via the ApplicationContext");}//這里的this.beanFactory在另一個抽象方法refreshBeanFactory的設置的return this.beanFactory;}} }GenericApplicationContext:
public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {@Overridepublic final ConfigurableListableBeanFactory getBeanFactory() {//同樣這里的this.beanFactory在另一個抽象方法中設置 return this.beanFactory;} }大家有空可以自己進去看看里面的源碼!里面真是高深莫測!
總結
以上是生活随笔為你收集整理的一篇博客读懂设计模式之---模板方法模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 集合Collection常见知
- 下一篇: matlab m文件的编写,Matlab