Java設計模式——模板設計模式

時間最考驗人發表於2021-10-30

模板設計模式

1.模板模式簡介

模板模式(Template ):模板方法模式是類的行為模式。準備一個抽象類,將部分邏輯以具體方法以及具體建構函式的形式實現,然後宣告一些抽象方法來迫使子類實現剩餘的邏輯。不同的子類可以以不同的方式實現這些抽象方法,從而對剩餘的邏輯有不同的實現。這就是模板方法模式的用意。

2.模板模式的結構

模式中的角色:

抽象類(AbstractClass):實現了模板方法,定義了演算法的骨架。

具體類(ConcreteClass):實現抽象類中的抽象方法,已完成完整的演算法。

image

3.通用程式碼如下

抽象模板類:

public abstract class AbstractClass {
     //基本方法
     protected abstract void doSomething();
     //基本方法
     protected abstract void doAnything();
     //模板方法
     public void templateMethod(){
             /*

呼叫基本方法,完成相關的邏輯

            this.doAnything();
            this.doSomething();
    }
}

具體模板類:

public class ConcreteClass1 extends AbstractClass {
     //實現基本方法
     protected void doAnything() {
             //業務邏輯處理
     }
     protected void doSomething() {
             //業務邏輯處理
     }
}
public class ConcreteClass2 extends AbstractClass {     //實現基本方法
     protected void doAnything() {
             //業務邏輯處理
     }
     protected void doSomething() {
             //業務邏輯處理
     }
}

場景類:

public class Client {
     public static void main(String[] args) {
             AbstractClass class1 = new ConcreteClass1();
             AbstractClass class2 = new ConcreteClass2();               
             //呼叫模板方法
             class1.templateMethod();
             class2.templateMethod();
     }

4.案例講解

需求

  • 有多個類,完成不同的job

  • 要求能夠得到各自的完成時間

1.)傳統方式實現

程式碼

package Abstract;

public class AbstractExercise {
    public static void main(String[] args) {
        AA aa = new AA();
        aa.calcTime();

        BB bb = new BB();
        bb.calcTime();
    }
}
class AA {
    // 計算任務1
    // 1 + 2 + ...+ 100000
    public void calcTime() {
        //得到開始時間
        long start = System.currentTimeMillis();
        job(); // 計算執行任務的時間
        // 得到結束時間
        long end = System.currentTimeMillis();
        System.out.println("AA 執行的時間 " + (end - start) + "毫秒");
    }

    long sum = 0;
    public void job(){
        for (int i = 1; i <= 100000; i++) {
            sum += i;
        }
    }
}

class BB {
    // 計算任務2
    // 1*1 + 2*2 +... 10000*10000
    public void calcTime() {
        //得到開始時間
        long start = System.currentTimeMillis();
        job(); // 計算執行任務的時間
        // 得到結束時間
        long end = System.currentTimeMillis();
        System.out.println("BB 執行的時間 " + (end - start) + "毫秒");
    }
    long sum = 0;
    public void job(){
        for (int i = 1; i <= 10000; i++) {
            sum += i * i;
        }
    }
}
// CC類 DD類.......

對於不同的任務它們有自己各自的執行方式,我們需要做的是統計它們各自執行完任務所花費的時間。我們通過觀察發現計算時間的方法被重複的使用,方法是一樣的方法只是各個任務執行的細節不同罷了,如果有CC類 、DD類.......的不同任務job()——因此我們可以將其設定為抽象方法!,那麼計算時間的方法calcTime()要在每一個類中使用!這樣程式碼就大量的重複了,不利於修改與維護!——因此我們可以將其設定為模板方法!

2.)模板設計模式實現

抽象模板類(AbstractClass)

package Abstract;

public abstract class Tempalte { //父類——模板類
    public abstract void job();// 抽象方法
	
	// 模板方法
    public void calcTime() { // 實現方法,呼叫job()方法
        //得到開始時間
        long start = System.currentTimeMillis();
        job(); // 計算執行任務的時間————動態繫結機制
        // 得到結束時間
        long end = System.currentTimeMillis();
        System.out.println("任務執行的時間 " + (end - start) + "毫秒");
    }
}

具體模板類(ConcreteClass)

package Abstract;

public class AA extends Tempalte{
    // 計算任務1
    // 1 + 2 + ...+ 100000
    long sum = 0;
    @Override
    public void job(){
        for (int i = 1; i <= 100000; i++) {
            sum += i;
        }
    }
}

package Abstract;

public class BB extends Tempalte{
    // 計算任務2
    // 1*1 + 2*2 +... 10000*10000
    long sum = 0;
    @Override
    public void job(){
        for (int i = 1; i <= 10000; i++) {
            sum += i * i;
        }
    }
}

 測試類(ConcreteClass)

package Abstract;

public class Application {
    public static void main(String[] args) {
        Tempalte aa = new AA();
        aa.calcTime(); // 動態繫結機制,對多型的理解
        Tempalte bb = new BB();
        bb.calcTime();
    }
}

5.模式模式優缺點:

1.)優點

模板方法模式通過把不變的行為搬移到超類,去除了子類中的重複程式碼。子類實現演算法的某些細節,有助於演算法的擴充套件。通過一個父類呼叫子類實現的操作,通過子類擴充套件增加新的行為,符合“開放-封閉原則”。

2.)缺點

每個不同的實現都需要定義一個子類,這會導致類的個數的增加,設計更加抽象。

3.)適用場景

在某些類的演算法中,用了相同的方法,造成程式碼的重複。控制子類擴充套件,子類必須遵守演算法規則。

注:如果文章有任何錯誤或不足,請各位大佬盡情指出,評論留言留下您寶貴的建議!如果這篇文章對你有些許幫助,希望可愛親切的您點個贊推薦一手,非常感謝啦

相關文章