日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > asp.net >内容正文

asp.net

一篇博客读懂设计模式之---模板方法模式

發(fā)布時(shí)間:2025/3/12 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一篇博客读懂设计模式之---模板方法模式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

設(shè)計(jì)模式之模板方法模式:

定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟

簡(jiǎn)而言之就是:父類定義了骨架(調(diào)用哪些方法及其順序),某些特定的方法由具體的子類來(lái)實(shí)現(xiàn)。
所以呢?在父類模板方法中是有兩類方法的:

  • 共同的方法:所有子類都必須用到的方法,類似于定義了一個(gè)框架,通常不用abstract而是final來(lái)修飾,防止子類重寫(xiě),像下面的play方法
  • 不同的方法:子類需要重寫(xiě)或者覆蓋的方法,這種方法也分為兩種:
    1). 抽象方法:父類是抽象方法,子類必須實(shí)現(xiàn)的,如下面的startGame,endGame方法;
    2). 鉤子方法:父類中是一個(gè)空方法,子類繼承的時(shí)候默認(rèn)也是空的,這個(gè)方法有什么用呢?子類可以通過(guò)這個(gè)方法來(lái)自定義自己的其他一些步驟和過(guò)程,從而達(dá)到控制父類的目的。
  • 我們將創(chuàng)建一個(gè)定義操作的 Game 抽象類,其中,模板方法設(shè)置為 final,這樣它就不會(huì)被重寫(xiě)。BasketballGame和 FootballGame 是擴(kuò)展了 Game 的實(shí)體類,它們重寫(xiě)了抽象類的方法。

    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)建擴(kuò)展了上述類的實(shí)體類:

    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. 使用測(cè)試類測(cè)試:

    public class TemplMain {public static void main(String[] args) {Game game = new FootballGame();//這樣如果你想要改變其他球類,只需要換成下面這種形式,其他不用改變//Game game = new BasketballGame();game.play();} }

    再升級(jí)一下,舉另一個(gè)例子:


    接口描述的是一種共性,一種動(dòng)作action;
    抽象類描述的是一個(gè)模板,一個(gè)特定的過(guò)程;
    而子類則是可以根據(jù)自己的需要定制自己的過(guò)程。

    不過(guò),這樣做的好處又是什么呢?

  • 將族群進(jìn)行隔離,像上面的圖一樣,我們可以將不同種類的人,美洲人,亞洲人進(jìn)行隔離,而不互相影響;
  • 可以將一些日志和共性的動(dòng)作很好的分離,規(guī)范子類的動(dòng)作。
  • 其實(shí)我們?cè)谝恍┛蚣?#xff0c;如spring,mybatis等都可以看到模板方法模式的影子,下面簡(jiǎn)單舉一下例子:
    像mybatis的Executor接口:

    你就可以很明顯的看到這種模式:

    spring中的模板方法模式:

    spring模板方法我來(lái)摘抄一些重點(diǎn)給大家看看:
    下面的代碼展示了Spring IOC容器初始化時(shí)運(yùn)用到的模板方法模式。(截取部分關(guān)鍵代碼)
    1、首先定義一個(gè)接口ConfigurableApplicationContext,聲明模板方法refresh

    public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable {/**聲明了一個(gè)模板方法*/void refresh() throws BeansException, IllegalStateException; }

    2、抽象類AbstractApplicationContext實(shí)現(xiàn)了接口,主要實(shí)現(xiàn)了模板方法refresh(這個(gè)方法很重要,是各種IOC容器初始化的入口)的邏輯:

    public abstract class AbstractApplicationContext extends DefaultResourceLoaderimplements ConfigurableApplicationContext, DisposableBean {/**模板方法的具體實(shí)現(xiàn)*/public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();//注意這個(gè)方法是,里面調(diào)用了兩個(gè)抽象方法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 {//注意這個(gè)方法是鉤子方法,點(diǎn)進(jìn)去父類看可以發(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();//注意這個(gè)方法是鉤子方法// 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;}}} }

    這里最主要有一個(gè)抽象方法obtainFreshBeanFactory、兩個(gè)鉤子方法postProcessBeanFactory和onRefresh,看看他們?cè)陬愔械亩x
    看看獲取Spring容器的抽象方法:

    /**其實(shí)他內(nèi)部只調(diào)用了兩個(gè)抽象方法**/ protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;}//上面兩個(gè)方法就是下面這兩個(gè)方法,可以看到他們都是抽象方法,等待具體的子類去實(shí)現(xiàn)protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

    3、具體實(shí)現(xiàn)的子類,實(shí)現(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在另一個(gè)抽象方法refreshBeanFactory的設(shè)置的return this.beanFactory;}} }

    GenericApplicationContext:

    public class GenericApplicationContext extends AbstractApplicationContext implements BeanDefinitionRegistry {@Overridepublic final ConfigurableListableBeanFactory getBeanFactory() {//同樣這里的this.beanFactory在另一個(gè)抽象方法中設(shè)置 return this.beanFactory;} }

    大家有空可以自己進(jìn)去看看里面的源碼!里面真是高深莫測(cè)!

    總結(jié)

    以上是生活随笔為你收集整理的一篇博客读懂设计模式之---模板方法模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。