標籤:java java設計模式 模版方法
源碼均以JDK1.8作為參考
1.定義:
定義一個操作中的演算法的架構,而將一些步驟延遲到子類中。使得子類可以不改變一個演算法的機構即可重定義該演算法的某些特定步驟。
2.解析:
通用類圖:
類圖解析:
模板方法模式非常簡單,僅僅使用了Java的繼承機制,但它是一個應用非常廣泛的模式。
2.1.抽象模板(AbstractClass)
主要定義了模板中一些基本操作(方法),它的方法分為兩類:
基本方法:
基本方法也叫基本操作,是由子類實現的方法,並且被模板方法被調用。
模板方法:
可以由一個或幾個,一般是一個具體的方法,也就是一個架構,實現對基本方法的調度,完成固定的邏輯。
2.2.具體模板(ConcreteClass1和ConcreteClass2)
實現了父類所定義的一個或多個抽象方法,也就是父類定義的基本方法在子類中得以實現。
3.具體應用:
3.1.抽象模板(AbstractClass)
public abstract class AbstractClass { // .. 基本方法 protected abstract void doSomething(); // .. 基本方法 protected abstract void doAnything(); // .. 模板方法 public void templateMethod(){ /* * 調用基本方法,完成相關的邏輯 */ this.doAnything(); this.doSomething(); }}
3.2.具體模板(ConcreteClass1和ConcreteClass2)
public class ConcreteClass1 extends AbstractClass { // .. 實現基本方法 protected void doAnything() { // .. 商務邏輯處理 } protected void doSomething() { // .. 商務邏輯處理 }}public class ConcreteClass2 extends AbstractClass { // .. 實現基本方法 protected void doAnything() { // .. 商務邏輯處理 } protected void doSomething() { // .. 商務邏輯處理 }}
3.3.情境類:
public class Client { public static void main(String[] args) { AbstractClass class1 = new ConcreteClass1(); AbstractClass class2 = new ConcreteClass2(); // .. 調用模板方法 class1.templateMethod(); class2.templateMethod(); }}
以上完成了一個簡單的Template Method模式的設計和應用,其實原理很簡單,Abstract抽象父類定義了基本方法和模板方法,實現了模板方法的具體邏輯,具體模板子類實現了抽象模板中的基本方法。
其實在JDK的源碼或者開源開源架構中,很多都是使用了這種設計模式,例如java.io.InputStream的實現,如下:
public abstract class InputStream implements Closeable { ... public abstract int read() throws IOException; public int read(byte b[]) throws IOException { return read(b, 0, b.length); } public int read(byte b[], int off, int len) throws IOException { if (b == null) { throw new NullPointerException(); } else if (off < 0 || len < 0 || len > b.length - off) { throw new IndexOutOfBoundsException(); } else if (len == 0) { return 0; } int c = read(); if (c == -1) { return -1; } b[off] = (byte)c; int i = 1; try { for (; i < len ; i++) { c = read(); if (c == -1) { break; } b[off + i] = (byte)c; } } catch (IOException ee) { } return i; } ...}
java.io.InputStream類中,模板方法public int read(byte b[], int off, int len)實現了具體的商務邏輯,而基本方法public abstract int read()則由子類實現,且在模板方法中被調用,由此實現了java.io.InputStream下所有子類都可以完成模板方法的操作。其實,在開源架構的源碼中,很容易看到類似的設計。
4.應用情境:
可否還記得物件導向的四個特徵呢:封裝、繼承、多態、抽象。Template Method設計模式就是充分的利用了面對對象的特性,高度抽象類別與類之間的行為,將公用部分交由抽象父類去實現,行為由父類控制,子類實現。基於此類的設計方式可以很容易的做到擴充,使得在後期更加容易維護。
應用情境:
·多個子類有公有的方法,並且邏輯基本相同時。
·重要、複雜的演算法,可以把核心演算法設計為模板方法,周邊的相關細節功能則由各個子類實現。
·重構時,模板方法模式是一個經常使用的模式,把相同的代碼抽取到父類中,然後通過鉤子函數約束其行為
5.總結:
Template Method(模板方法)設計模式是日常中很常用的一個設計模式,或許你沒有聽過Template Method(模板方法)設計模式這個稱呼,但是一定接觸過這個設計模式,這是在對類或結構進行設計時,高度抽象的一個模式,可以高度的抽象類別間共性,完成良好的設計。
註:本人是參照《設計模式之禪》和《設計模式》兩本書學習所得,其中加入了自己對於Iterator設計模式的理解,以及對於JDK中源碼的理解。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Java設計模式(四) 之 模板方法模式