java模板設計模式


1、概述

    模板設計模式定義:定義一個操作中的算法骨架,將步驟延遲到子類中。

    模板設計模式是一種行為設計模式,一般是准備一個抽象類,將部分邏輯以具體方法或者具體的構造函數實現,然后聲明一些抽象方法,這樣可以強制子類實現剩余的邏輯。不同的子類以不同的方式實現這些抽象方法,從而對剩余的邏輯有不同的實現。這就是模板設計模式能達成的功能。

    適用於一些復雜操作進行步驟分割、抽取公共部分由抽象父類實現、將不同的部分在父類中定義抽象實現、而將具體實現過程由子類完成。對於整體步驟很固定,但是某些部分易變,可以將易變的部分抽取出來,供子類實現。

    角色:

        抽象類:實現模板方法、定義算法骨架

        具體類:實現抽象類中的抽象方法,完成特定的算法


2、代碼示例

    我們舉一個比較常見的例子:將一個物品裝進冰箱。為了達到這個目的我們一般有如下幾步:

        a:打開冰箱門

        b:將物品裝進冰箱

        c:關上冰箱門

    上面的這三步其實就是“將一個物品裝進冰箱”這個算法的骨架。在這個算法中,物品這個字眼很重要,它是抽象的,而不是具體的,對於每個不同的物品,裝入的時候行為可能不同,這一點非常重要。比如:

        a:將一塊豬肉放進冰箱--->一塊豬肉這么小,直接放進去

        b:將一頭大象放進冰箱--->一頭大象這么大,切碎放進去

    上面只是不恰當的舉個例子,只是為了說明:針對與不同物品,放入冰箱的動作(行為)不同。

    特別注意:上面物品雖是抽象的,但是我最終想表達的是“將物品裝進冰箱”這個行為是抽象的。

package com.yefengyu.pattern.template;

public abstract class AbstractClass
{
    public final void execute()
    {
        open();
        put();
        close();
    }

    private void open()
    {
        System.out.println("打開冰箱");
    }

    private void close()
    {
        System.out.println("關閉冰箱");
    }

    protected abstract void put();
}
 

    上面的AbstractClass類中的execute方法就是一個算法骨架,它定義了復雜操作的許多步驟,其中需要注意:

    (1)AbstractClass是抽象類,因為子類需要繼承某些抽象方法

    (2)execute是算法骨架,讓外部調用,所以必須是public,但是又不想讓子類進行重寫,因此使用final關鍵字,如果重寫則導致整個流程混亂。

    (3)open和close方法是固定的步驟,定義為私有,不讓子類修改。

    (4)put方法是protected 的,保證子類可以重寫,但是其它類無法看到,又是abstract 則子類必須重寫。因為父類AbstractClass無法得知具體的物品該如何放入冰箱,只有靠子類去實現了。

    下面來實現兩個子類。

package com.yefengyu.pattern.template;

public class Pork extends AbstractClass
{
    @Override
    protected void put()
    {
        System.out.println("將一塊豬肉裝進冰箱:直接裝啊");
    }
}
package com.yefengyu.pattern.template;

public class Elephant extends AbstractClass
{
    @Override
    protected void put()
    {
        System.out.println("將大象裝入冰箱:你必須剁碎再裝入");
    }
}

    這兩個子類雖然在put中都只打印了一句話,但是我們可以想象這里的操作十分復雜,並且流程大不一樣。下面我們來實現客戶端代碼。

package com.yefengyu.pattern.template;

public class Client
{
    public static void main(String[] args)
    {
        AbstractClass abstractClass = new Pork();
        abstractClass.execute();

        System.out.println("-------------------");

        abstractClass = new Elephant();
        abstractClass.execute();
    }
}

    運行結果如下

模板設計模式

    通過上面的例子,我么可以看出:不同的實現類,重寫的抽象方法的邏輯不同,導致算法執行的結果也不相同,但是算法骨架是沒有改變的。


3、案例剖析

    大家應該使用Thread類,在學習的時候,一定都注意到這個問題,我們重寫了run方法,但是線程啟動的時候,為什么使用start方法?

package com.yefengyu.pattern.template;

public class MyThread
{
    public static void main(String[] args)
    {
        Thread thread = new Thread(){
            @Override
            public void run()
            {
                System.out.println("###");
            }
        };
        
        thread.start();
    }
}

    其實Thread類也使用了模板設計模式,只是有些地方有些差異。

image

    總結:

    start方法就是算法骨架的入口,它定義算法的骨架;start0()方法是本地方法,該方法最終還是調用了Thread的run方法,具體細節不做介紹。那么我們可以簡單的認為start0()就是run方法,那么這就和模板設計模式非常相似:

    start方法:算法框架入口和骨架,和上面的AbstractClass的execute方法對應。

    start0方法:可以看作run方法,雖然run方法不是抽象方法,但是也可以復寫,並且一般必須復寫,不然線程沒啥業務,有啥意義呢?

    Thread線程的使用start啟動,做了很多其它的事情,也在某個地方調用了run方法,它是線程完整執行的入口,就和上面的AbstractClass的execute方法一樣;如果線程調用run方法啟動,只是和普通方法調用一樣,無法真正啟動一個線程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM