版權聲明:尊重部落客原創文章,轉載請注明出處哦~http://blog.csdn.net/eson_15/article/details/51323902
這一節主要來學習一下設計模式中的模闆方法模式。我們先來看一個例子:假如現在老闆讓你做一個汽車的模型,要求隻要完成基本功能即可,不考慮擴充性,那你會怎麼做呢?我們首先會根據經驗設計一個類圖:
由這個類圖可知,非常簡單的實作了悍馬車,該車有兩個型号h1和h2。那現在我們開始實作這兩個型号的悍馬車,首先我們得把抽象類寫好,然後兩個不同的模型實作類通過簡單的繼承就可以實作要求。首先看看抽象類的代碼:
public abstract class hummermodel {
public abstract void start(); //發動
public abstract void stop(); //停止
public abstract void alarm(); //鳴笛
public abstract void engineboom(); //轟鳴
public abstract void run(); //車總歸要跑
}
簡單到不行,下面我們來實作兩個悍馬的模型:
//悍馬h1
public class hummerh1 implements hummermodel {
@override
public void start() {
system.out.println("h1發動……");
}
public void stop() {
system.out.println("h1停止……");
public void alarm() {
system.out.println("h1鳴笛……");
public void engineboom() {
system.out.println("h1轟鳴……");
public void run() {
this.start();
this.engineboom();
this.alarm();
this.stop();
//悍馬h2
public class hummerh2 implements hummermodel {
system.out.println("h2發動……");
system.out.println("h2停止……");
system.out.println("h2鳴笛……");
system.out.println("h2轟鳴……");
很明顯,已經發現代碼有點問題了,兩個悍馬的run方法完全相同。是以這個run方法應該出現在抽象類中,不應該在實作類中,抽象是所有子類的共性封裝。是以我們修改一下抽象類:
public void run() { //車總歸要跑
這樣兩個實作類就不用實作run方法了,可以直接拿來用。其實,這就是模闆方法模式。
public abstract class abstractclass {
//基本方法
protected abstract void dosomething();
protected abstract void doanything();
//模闆方法
public void templatemethod() {
//調用基本方法,完成相關的邏輯
this.doanything();
this.dosomething();
具體實作類就不寫了……
優點:
1)封裝不變部分,擴充可變部分:把認為不變部分的算法封裝到父類實作,可變部分則可以通過繼承來實作,很容易擴充。
2)提取公共部分代碼,便于維護:上面悍馬的例子就是個很好的解釋。
3)行為由父類控制,由子類實作。
缺點:
模闆方法模式颠倒了我們平常的設計習慣:抽象類負責聲明最抽象、最一般的事物屬性和方法,實作類實作具體的事物屬性和方法。在複雜的項目中可能會帶來代碼閱讀的難度。
還是上面那個悍馬的例子,現在老闆說這車幹嘛跑起來就要鳴笛,太吵了,難道不是應該讓使用者決定它是否要鳴笛麼?好像确實是這樣的……那好辦,我們可以修改一下抽象模闆類中的方法:
protected abstract void start(); //發動
protected abstract void stop(); //停止
protected abstract void alarm(); //鳴笛
protected abstract void engineboom(); //轟鳴
final public void run() { //車總歸要跑
if(this.isalarm()) {//想讓它叫就叫,不想就不叫
this.alarm();
}
protected boolean isalarm() { //我們加了一個判斷方法,預設傳回true
return true;
我們在模闆類中增加了一個判斷方法來判斷是否要鳴笛,現在就好辦了,具體實作類隻要重寫這個方法就可以做到人為控制是否要鳴笛了,下面我們來看一下實作類:
public class hummerh1 extends hummermodel {
private boolean alarmflag = true; //判斷标記
protected boolean isalarm() { //覆寫isalarm方法,傳回判斷标記
return this.alarmflag;
public void setalarm(boolean isalarm) { //設定判斷标記
this.alarmflag = isalarm;
這個實作很好,我們在實作類中定義一個判斷标記,然後對外提供一個public接口setalarm來讓外界設定這個判斷标記,這就像是開關一樣,想讓它ture和false都行。這個isalarm方法俗稱鈎子方法。有了鈎子方法的模闆方法模式才算完美,大家可以想象一下,由子類的一個方法傳回值決定公共部分的執行結果,這個是很有吸引力的。我們來測試一下:
public class test {
public static void main(string[] args) throws ioexception {
system.out.println("----h1型悍馬----");
system.out.println("是否需要喇叭聲響? 0-不需要 1-需要");
string type = new bufferedreader(new inputstreamreader(system.in)).readline();
hummerh1 h1 = new hummerh1();
if(type.equals("0")) {
h1.setalarm(false);
h1.run();
當輸入不同的指令後,就會決定不同的動作:即要不要鳴笛,至此,這個模闆方法模式就介紹完了。
_____________________________________________________________________________________________________________________________________________________
-----樂于分享,共同進步!