最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java設(shè)計模式之模板方法模式詳解

 更新時間:2021年06月23日 11:35:28   作者:當(dāng)代唐寅  
這篇文章主要為大家詳細介紹了java設(shè)計模式之模板方法模式的相關(guān)資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

一、什么是模板方法模式

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

  通俗的講,模板方法模式是通過把不變行為搬到超類,去除子類里面的重復(fù)代碼提現(xiàn)它的優(yōu)勢,它提供了一個很好的代碼復(fù)用平臺。當(dāng)不可變和可變的方法在子類中混合在一起的時候,不變的方法就會在子類中多次出現(xiàn),這樣如果摸個方法需要修改則需要修改很多個,雖然這個這個問題在設(shè)計之初就應(yīng)該想好。這個時候模板方法模式就起到了作用了,通過模板方法模式把這些重復(fù)出現(xiàn)的方法搬到單一的地方,這樣就可以幫助子類擺脫重復(fù)不變的糾纏。

  舉個好懂的例子,小時候筆者家里窮,在農(nóng)村上小學(xué)的時候考試都是每個學(xué)生手抄試卷,因為那個時候?qū)W校還沒有試卷印刷。全班五十多個學(xué)生每個學(xué)生都要重復(fù)抄一遍黑板的試卷,并且像筆者這樣的近視眼很容易就抄錯了,8抄成3,7抄成1等到,然后明明做對了但是分數(shù)就是不高,導(dǎo)致筆者一直是全班倒數(shù)。這就是個很嚴重的重復(fù)不可變的問題,現(xiàn)在條件好了不少,學(xué)生不需要抄試卷,試卷印刷就解決了這個重復(fù)抄試卷的問題。模板方法也是類似。

二、模式對比

1、抄試卷模式

筆者就以抄試卷模式為名來闡述重復(fù)不變帶來的不便,下面會對該模式進行改進。

學(xué)生甲抄的試卷

public class TestPaperA {
 //試卷第一題
 public void testQuestion1(){
  System.out.println("小龍女是楊過的什么親戚?() A.小姨媽 B.大姨媽 C.姑媽 D.舅媽");
  System.out.println("答案:C");
 }
 
 //試卷第二題
 public void testQuestion2(){
  System.out.println("全真教的首任掌門是誰?A.周伯通 B.歐陽鋒 C.王重陽 D.西門吹牛");
  System.out.println("答案:C");
 }
 
 //試卷第三題
 public void testQuestion3(){
  System.out.println("《天龍八部》中被封為南院大王的大俠是誰?A.段譽 B.喬峰 C.慕容復(fù) D.段智興");
  System.out.println("答案:B");
 }
}

學(xué)生乙抄的試卷

public class TestPaperB {
 //試卷第一題
 public void testQuestion1(){
  System.out.println("小龍女是楊過的什么親戚?() A.小姨媽 B.大姨媽 C.姑媽 D.舅媽");
  System.out.println("答案:A");
 }
 
 //試卷第二題
 public void testQuestion2(){
  System.out.println("全真教的首任掌門是誰?A.周伯通 B.歐陽鋒 C.王重陽 D.西門吹牛");
  System.out.println("答案:C");
 }
 
 //試卷第三題
 public void testQuestion3(){
  System.out.println("《天龍八部》中被封為南院大王的大俠是誰?A.段譽 B.喬峰 C.慕容復(fù) D.段智興");
  System.out.println("答案:D");
 }
}

客戶端代碼

public class ShowAnswer {

 public static void main(String[] args) {
  System.out.println("學(xué)生甲的試卷");
  TestPaperA stuA = new TestPaperA();
  stuA.testQuestion1();
  stuA.testQuestion2();
  stuA.testQuestion3();
  System.out.println("學(xué)生乙的試卷");
  TestPaperB stuB = new TestPaperB();
  stuB.testQuestion1();
  stuB.testQuestion2();
  stuB.testQuestion3();
 }

}

很容易發(fā)現(xiàn)上面兩個學(xué)生抄的試卷有很多重復(fù)的地方,比如試卷的題目,輸出答案的方法,這些都在每個學(xué)生試卷類中混合在一起了,既不利于維護,也不利于瀏覽,下面看一下模板方法模式是怎么改進的。

2、模板方法模式

將每個學(xué)生試卷的重復(fù)部分提取出來,題目,作答等等。

首先改造試卷類,將該類改為抽象類,在該類中我添加了三個抽象的方法用于子類實現(xiàn),學(xué)生都是要作答的,但是答案不一樣,所以可以將作答的過程作為重復(fù)不變的方法提取出來,代碼如下。

public abstract class TestPaper {
 //試卷第一題
 public void testQuestion1(){
  System.out.println("小龍女是楊過的什么親戚?() A.小姨媽 B.大姨媽 C.姑媽 D.舅媽");
  System.out.println("答案:" + answer1());
 }
 
 //試卷第二題
 public void testQuestion2(){
  System.out.println("全真教的首任掌門是誰?A.周伯通 B.歐陽鋒 C.王重陽 D.西門吹牛");
  System.out.println("答案:" + answer2());
 }
 
 //試卷第三題
 public void testQuestion3(){
  System.out.println("《天龍八部》中被封為南院大王的大俠是誰?A.段譽 B.喬峰 C.慕容復(fù) D.段智興");
  System.out.println("答案:" + answer3());
 }
 
 //這三個鉤子方法是給每個子類去實現(xiàn),并返回答案的
 public abstract String answer1();
 public abstract String answer2();
 public abstract String answer3();
 
 //模板方法,考試的過程,定義基本的考試過程,子類回調(diào)
 public void exam(){
  testQuestion1();
  testQuestion2();
  testQuestion3();
 }
}

首先來看第一個學(xué)生的考試情況

public class TestPaperA extends TestPaper{

 @Override
 public String answer1() {
  return "A";
 }

 @Override
 public String answer2() {
  return "B";
 }

 @Override
 public String answer3() {
  return "D";
 }
 
}

其他學(xué)生的試卷可能答案不是一樣的,但是基本的答題過程就是一樣的,所以就不重復(fù)寫了,下面看下客戶端代碼。

public class ShowAnswer {

 public static void main(String[] args) {
  TestPaper testPaper = new TestPaperA();
  testPaper.exam();
 }

}

可以看待客戶端代碼也減輕了很多,這樣邏輯清晰,利于維護,優(yōu)勢很明顯,下面看下具體答題情況。

小龍女是楊過的什么親戚?() A.小姨媽  B.大姨媽  C.姑媽  D.舅媽
答案:A
全真教的首任掌門是誰?A.周伯通 B.歐陽鋒 C.王重陽 D.西門吹牛
答案:B
《天龍八部》中被封為南院大王的大俠是誰?A.段譽 B.喬峰 C.慕容復(fù) D.段智興
答案:D

3、模板方法模式的基本結(jié)構(gòu)

AbstractClass是一個抽象類,其實就是一個抽象模板,定義并實現(xiàn)了一個模板方法。這個模板方法一般是一個具體的實現(xiàn),他給出了一些邏輯的骨架,而邏輯的組成在相應(yīng)的抽象類中,推遲到了子類實現(xiàn)。代碼如下

public abstract class AbstractClass {

 //一些抽象行為,可以理解為重復(fù)不變的方法,提取到抽象類
 public abstract void primitiveOperation1();
 public abstract void primitiveOperation2();
 
 //模板方法,給出了具體邏輯的骨架,而邏輯的組成是一些相應(yīng)的抽象操作,他們都推遲到子類實現(xiàn)
 public void templateMothed(){
  primitiveOperation1();
  primitiveOperation2();
 }
 
}

ConcreteClass,實現(xiàn)父類所定義的一個或多個抽象方法。每一個AbstractClass都可以有一個或者多個ConcreteClass與之對應(yīng),而每一個ConcreteClass都可以給出這些抽象方法(也就是骨架的組成步驟)的不同實現(xiàn),從而得到的實現(xiàn)都不同。

public class ConcreteClassA extends AbstractClass{

 @Override
 public void primitiveOperation1() {
  System.out.println("子類A的操作1");
 }

 @Override
 public void primitiveOperation2() {
  System.out.println("子類A的操作2");
 }

}
public class ConcreteClassB extends AbstractClass{

 @Override
 public void primitiveOperation1() {
  System.out.println("子類B的操作1");
 }

 @Override
 public void primitiveOperation2() {
  System.out.println("子類B的操作2");
 }

}

上面定義了兩個具體的實現(xiàn),更多的實現(xiàn)其實都是一致的,這里就不多多說了。下面看下客戶端代碼

public class Show {

 public static void main(String[] args) {
  AbstractClass c;
  c = new ConcreteClassA();
  c.templateMothed();
  c = new ConcreteClassB();
  c.templateMothed();
 }
 
}

輸入如下

子類A的操作1
子類A的操作2
子類B的操作1
子類B的操作2

4、UML圖

三、總結(jié)

模板方法模式就是為了將重復(fù)不變的代碼提取到一個抽象類中。當(dāng)我們要完成在某一細節(jié)層次一致的一個過程或一系列步驟,但其個別步驟在更詳細的層次上的實現(xiàn)可能不同時,我們通??紤]用模板方法模式來處理。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SPRING FRAMEWORK BEAN作用域和生命周期原理解析

    SPRING FRAMEWORK BEAN作用域和生命周期原理解析

    這篇文章主要介紹了SPRING FRAMEWORK BEAN作用域和生命周期原理解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • Java的NIO之通道channel詳解

    Java的NIO之通道channel詳解

    這篇文章主要介紹了Java的NIO之通道channel詳解,通道channel由java.nio.channels 包定義的,Channel 表示IO源與目標(biāo)打開的連接,Channel類類似于傳統(tǒng)的"流",只不過Channel本身不能直接訪問數(shù)據(jù),Channel只能與Buffer進行交互,需要的朋友可以參考下
    2023-10-10
  • eclipse自動創(chuàng)建SpringBoot項目報錯的解決

    eclipse自動創(chuàng)建SpringBoot項目報錯的解決

    這篇文章主要介紹了eclipse自動創(chuàng)建SpringBoot項目報錯的解決方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java中類的定義和初始化示例詳解

    Java中類的定義和初始化示例詳解

    這篇文章主要給大家介紹了關(guān)于Java中類的定義和初始化的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • 數(shù)據(jù)結(jié)構(gòu)與算法之并查集(不相交集合)

    數(shù)據(jù)結(jié)構(gòu)與算法之并查集(不相交集合)

    并查集是一種挺高效的數(shù)據(jù)結(jié)構(gòu)。實現(xiàn)簡單,只是所有元素統(tǒng)一遵從一個規(guī)律所以讓辦事情的效率高效起來。這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)與算法——并查集(不相交集合),需要的朋友可以參考下
    2019-11-11
  • Dom4j解析xml復(fù)雜多節(jié)點報文方式

    Dom4j解析xml復(fù)雜多節(jié)點報文方式

    這篇文章主要介紹了Dom4j解析xml復(fù)雜多節(jié)點報文方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 使用mybatis報Invalid bound statement解決分析

    使用mybatis報Invalid bound statement解決分析

    這篇文章主要為大家介紹了使用mybatis報Invalid bound statement原因解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-12-12
  • Java數(shù)據(jù)結(jié)構(gòu)與算法實現(xiàn)遞歸與回溯

    Java數(shù)據(jù)結(jié)構(gòu)與算法實現(xiàn)遞歸與回溯

    本文主要介紹了Java數(shù)據(jù)結(jié)構(gòu)與算法實現(xiàn)遞歸與回溯,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 深入學(xué)習(xí)springboot線程池的使用和擴展

    深入學(xué)習(xí)springboot線程池的使用和擴展

    這篇文章主要介紹了深入學(xué)習(xí)springboot線程池的使用和擴展,springboot框架提供了@Async注解,幫助我們更方便的將業(yè)務(wù)邏輯提交到線程池中異步執(zhí)行,需要的朋友可以參考下
    2019-06-06
  • IDEA使用maven創(chuàng)建hibernate項目的實現(xiàn)步驟(圖文)

    IDEA使用maven創(chuàng)建hibernate項目的實現(xiàn)步驟(圖文)

    本文主要介紹了IDEA使用maven創(chuàng)建hibernate項目的實現(xiàn)步驟,包括創(chuàng)建Maven項目,配置Hibernate,以及創(chuàng)建實體類映射到數(shù)據(jù)庫等步驟,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08

最新評論

旬邑县| 德格县| 马山县| 井冈山市| 吕梁市| 北流市| 建湖县| 延川县| 阿巴嘎旗| 海口市| 肇源县| 屯昌县| 奎屯市| 渝中区| 巴彦淖尔市| 济阳县| 武冈市| 祥云县| 甘肃省| 绿春县| 武川县| 岳普湖县| 万年县| 当涂县| 定襄县| 健康| 聂拉木县| 商都县| 邯郸市| 东光县| 修文县| 岑巩县| 讷河市| 门头沟区| 海淀区| 澜沧| 波密县| 苏尼特右旗| 雷波县| 龙胜| 茶陵县|