<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          模板模式:一種體現(xiàn)多態(tài)的設(shè)計(jì)模式

          共 3441字,需瀏覽 7分鐘

           ·

          2020-12-08 21:26

          點(diǎn)擊上方「藍(lán)字」關(guān)注我們

          0x01:模板模式

          模板模式(Template),又叫模板方法模式(Template Method),在一個抽象類公開定義了執(zhí)行它的方法的模板。它的子類可以按需重寫方法實(shí)現(xiàn),但調(diào)用將以抽象類中定義的方式進(jìn)行。模板方法模式:定義一個操作中的算法的骨架,而將一些步驟延遲到子類中,使得子類可以不改變一個算法的結(jié)構(gòu),就可以重定義該算法的某些特定步驟。UML類圖如下:

          ?主要包含如下角色:

          • AbstractClass(抽象模板類):在抽象類中定義了一系列基本操作,這些基本操作可以是具體的,也可以是抽象的,每一個基本操作對應(yīng)算法的一個步驟,在其子類中可以重定義或?qū)崿F(xiàn)這些步驟。同時,在抽象類中實(shí)現(xiàn)了一個模板方法(Template Method),用于定義一個算法的框架,模板方法不僅可以調(diào)用在抽象類中實(shí)現(xiàn)的基本方法,也可以調(diào)用在抽象類的子類中實(shí)現(xiàn)的基本方法,還可以調(diào)用其他對象中的方法。

          • ConcreteCalss(具體模板子類):它是抽象類的子類,用于實(shí)現(xiàn)在父類中聲明的抽象基本操作以完成子類特定算法的步驟,也可以覆蓋在父類中已經(jīng)實(shí)現(xiàn)的具體基本操作。


          抽象模板類:定義一個模板方法來組合sing()和dance()兩個方法形成一個算法,然后讓子類重定義這兩個方法。

          public?abstract?class?AbstractClass?{

          ????public?abstract?void?sing(String?name);

          ????public?abstract?void?dance(String?name);

          ????public?void?templateMethd(String?name)?{
          ????????sing(name);
          ????????dance(name);
          ????}

          }

          具體模板類:這里定義兩個具體模板類,ConcreteClassLiMing及ConcreteClassLiuDeHua來進(jìn)行測試,繼承抽象模板類,實(shí)現(xiàn)具體方法。

          public?class?ConcreteClassLiMing?extends?AbstractClass?{

          ????@Override
          ????public?void?sing(String?name)?{
          ????????System.out.println(name?+?"在唱歌");
          ????}

          ????@Override
          ????public?void?dance(String?name)?{
          ????????System.out.println(name?+?"在跳舞");
          ????}

          }

          public?class?ConcreteClassLiuDeHua?extends?AbstractClass?{

          ????@Override
          ????public?void?sing(String?name)?{
          ????????System.out.println(name?+?"在唱歌");
          ????}

          ????@Override
          ????public?void?dance(String?name)?{
          ????????System.out.println(name?+?"在跳舞");
          ????}

          }

          Client客戶端:

          public?class?Client?{

          ????public?static?void?main(String[]?args)?{
          ????????AbstractClass?abstractClass?=?null;

          ????????abstractClass?=?new?ConcreteClassLiMing();
          ????????abstractClass.templateMethd("黎明");

          ????????abstractClass?=?new?ConcreteClassLiuDeHua();
          ????????abstractClass.templateMethd("劉德華");
          ????}

          }

          通過以上代碼就實(shí)現(xiàn)了一個簡單的模板模式,模板模式的優(yōu)點(diǎn):封裝不變部分,擴(kuò)展可變部分。提取公共代碼,便于維護(hù)。行為由父類控制,子類實(shí)現(xiàn);缺點(diǎn):每一個不同的實(shí)現(xiàn)都需要一個子類來實(shí)現(xiàn),導(dǎo)致類的個數(shù)增加,使得系統(tǒng)更加龐大。


          0x02:JDK中的模板模式

          如果有了解過java.util.concurrent.locks包的AbstractQueuedSynchronizer類(簡稱AQS),就會發(fā)現(xiàn)AbstractQueuedSynchronizer類(同步器)是一個非常經(jīng)典的模板模式。如果需要自定義同步器,一般方法是:繼承AQS,并重寫指定方法(無非是按照自己定義的規(guī)則對state的獲取與釋放);將AQS組合在自定義同步組件的實(shí)現(xiàn)中,并調(diào)用模板方法,而這些模板方法會調(diào)用重寫的方法。

          //該線程是否正在獨(dú)占資源。只有用到condition才需要去實(shí)現(xiàn)它。
          isHeldExclusively();
          //獨(dú)占方式。嘗試獲取資源,成功則返回true,失敗則返回false。
          tryAcquire(int);
          //獨(dú)占方式。嘗試釋放資源,成功則返回true,失敗則返回false。
          tryRelease(int);
          ////共享方式。嘗試獲取資源。負(fù)數(shù)表示失敗;0表示成功,但沒有剩余可用資源;正數(shù)表示成功,且有剩余資源。
          tryAcquireShared(int);
          ////共享方式。嘗試釋放資源,成功則返回true,失敗則返回false。
          tryReleaseShared(int);

          默認(rèn)情況下,以上這些方法都拋出 UnsupportedOperationException。這些方法的實(shí)現(xiàn)必須是內(nèi)部線程安全的,并且通常應(yīng)該簡短而不是阻塞。AQS類中的其他方法都是final ,所以無法被其他類使用,只有這幾個方法可以被其他類使用。


          0x03:Spring中的模板模式

          Spring作為一個特優(yōu)秀的框架,底層大量使用模板模式。以Spring的事務(wù)管理器來講下Spring中的模板模式。

          AbstractPlatformTransactionManager是Spring中的模板抽象類,它的繼承關(guān)系圖如下:

          實(shí)現(xiàn)了PlatformTransactionManager接口,重載了接口中的方法。

          • 模板方法:事務(wù)管理器中抽象類中的模板方法不止一個,比如以下兩個方法

          //提交事務(wù)
          public?final?void?commit()

          //獲取TransactionStatus
          public?final?TransactionStatus?getTransaction()

          這兩個方法都對于自己要實(shí)現(xiàn)的邏輯搭建了一個骨架,主要的功能是由抽象方法完成,由子類來完成。

          • 抽象方法事務(wù)管理器抽象類中的抽象方法定義了多個,分別用于處理不同的業(yè)務(wù)邏輯,由子類實(shí)現(xiàn)其中具體的邏輯。

          //提交事務(wù)
          protected?abstract?void?doCommit(DefaultTransactionStatus?status);

          //回滾事務(wù)
          protected?abstract?void?doRollback(DefaultTransactionStatus?status);

          //開始事務(wù)
          protected?abstract?void?doBegin(Object?transaction,?TransactionDefinition?definition)

          //獲取當(dāng)前的事務(wù)對象
          protected?abstract?Object?doGetTransaction()

          抽象方法的定義便于子類去擴(kuò)展,在保證算法邏輯不變的情況下,子類能夠定制自己的實(shí)現(xiàn)。

          • 具體子類:其中有DataSourceTransactionManager、JtaTransactionManager、RabbitTransactionManager等,類繼承關(guān)系如下:

          另外還有JdbcTemplate、JpaTemplate等使用了模板模式。其他需要大家慢慢去發(fā)現(xiàn),去學(xué)習(xí)~~~

          書山有路勤為徑,學(xué)海無涯苦作舟!

          掃碼二維碼

          獲取更多精彩

          Java樂園

          有用!分享+在看?
          瀏覽 29
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产乱伦免费视频 | 大香蕉伊人成人电影 | 97乱伦视频 | 成人毛片一区二区三区无码 | 天天曰夜夜操 |