Java設計模式之模板方法設計模式——寫漂亮的程式碼————
阿新 • • 發佈:2019-02-15
Java設計模式,寫漂亮的程式碼
————模板方法設計模式
簡介:
模板方法設計模式是Java設計模式中很簡單、應用非常廣泛的的一種設計模式,該模式體現了程式設計的抽象思想(抽象是所有子類的共性封裝),
僅僅使用了Java的繼承機制。其實很可能在你寫程式碼的過程中已經使用過了很多次這種模式,只是你還不太清楚那就是模板方法設計模式。
接下來就讓我們一起去看看,到底什麼是模板方法設計模式呢?
首先看一下描述:
定義一個操作中的演算法的框架,而將一些步驟延遲到了子類中。使得子類可以不改變一個演算法的結構即可重定義該演算法的某些步驟。
UML類圖描述:
下圖就是模板方法設計模式的UML類圖描述,正如你所見,沒錯,就是這麼簡單,一目就能瞭然。
其中AbstractClass叫做抽象模板類,實現了模板方法,定義了演算法的骨架,它的方法分為兩類:
1. 基本方法:基本方法也叫作基本操作,是由子類實現的方法,並且在模板方法被呼叫.
2. 模板方法:可以有一個或者幾個,一般是一個具體方法,也就是一個框架,實現對基本方法的排程,完成固定的邏輯。
具體類:ConcreteClass:實現抽象類中的抽象方法,完成完整的演算法。
下面通過一個簡單的例子描述下模板方法模式的應用:
本例子通過模擬手機情景模式的過程,簡單描述下模板方法的應用:
public abstract class SceneMode {
//這裡定義了一個抽象類,即模板方法模式的抽象模板類,把子類共有的一些操作抽象到該類中,情景模式普遍就是響鈴和震動的操作,這裡將通用的流程放到該類中,具體的配置通過其子類來完成
private static final String TAG = "SceneMode";
private static final String DEFAULT_RING = "little Star";
private String mRing = DEFAULT_RING;
private boolean isRing;
private boolean isVibrating;
public void goModel() {
Log.d(TAG, "開啟模式:");
}
//共性方法的抽象,由子類去實現具體的情景模式名稱
public abstract String getSceneModelName();
public abstract boolean isRing();
public abstract boolean isVibration();
//鉤子函式,外界條件改變,影響了模板函式的執行
public void setRingMusic(String ringName) {
this.mRing = ringName;
};
private void playRing() {
this.isRing = true;
Log.d(TAG, "play: " + mRing);
}
private void vibrating() {
this.isVibrating = true;
Log.d(TAG, "vibrating");
}
private void startRing() {
if (isRing()) playRing();
}
private void startVibrating() {
if (isVibration()) vibrating();
}
private void stopRing() {
if (isRing) {
Log.d(TAG, "停止響鈴");
this.isRing = false;
}
}
private void stopVibration() {
if (isVibrating) {
Log.d(TAG, "停止震動");
this.isVibrating = false;
}
}
public final void called() {
//為了防止惡意的操作,一般模板方法都加上final關鍵字,不允許被重寫
Log.d(TAG, "called: 被呼叫");
new Thread() {
@Override
public void run() {
startRing();
startVibrating();
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
stopRing();
stopVibration();
}
}.start();
}
}
public class RingSceneMode extends SceneMode{
//子類響鈴模式,完成對應的配置,達到重定義父類called的動作
@Override
public String getSceneModelName() {
return "響鈴模式";
}
@Override
public boolean isRing() {
return true;
}
@Override
public boolean isVibration() {
return false;
}
}
public class VibrationSceneMode extends SceneMode{
//子類震動模式,完成對應的配置,達到重定義父類called的動作
@Override
public String getSceneModelName() {
return "振動模式";
}
@Override
public boolean isRing() {
return false;
}
@Override
public boolean isVibration() {
return true;
}
}
如下為場景類,建立不同的模式來完成對應的模式匹配,實現特定模式達到的效果
//1.設定RingMode
mSceneMode = new RingSceneMode();
mSceneMode.setRingMusic("lemon tree");
Log.d(TAG, mSceneMode.getSceneModelName());
mSceneMode.called();
//2.設定VibrationMode
mSceneMode = new VibrationSceneMode();
Log.d(TAG, mSceneMode.getSceneModelName());
mSceneMode.called();
//3.設定Ring + Vibration Mode
mSceneMode = new RingAndVibrationSceneMode();
mSceneMode.setRingMusic("lemon tree");
Log.d(TAG, mSceneMode.getSceneModelName());
mSceneMode.called();
模板方法模式的優點:
- 封裝不變部分,擴充套件可變部分;
- 提取公共部分程式碼,便於維護;
3. 行為由父類控制,子類實現。
模板方法模式的使用場景
- 多個子類有公有的方法,並且邏輯基本相同時。
- 重要複雜的演算法,可以把核心演算法設計為模板方法,周邊的相關細節功能則有各個子類實現。
- 重構時, 模板方法模式是一個經常使用的模式,把相同的程式碼抽取到父類中,然後通過鉤子函式(外界條件改變,影響到模板方法的執行)約束其行為。