背景:
設計模式是“前人”提煉的代碼思想的精華?什麼?這聽着太高大上了,我可沒用過?什麼,你沒用過?那不可能,作爲Android從業主,你沒setOnClickListener()嗎?你沒有抽取公共代碼到基類BaseActivity/BaseFragment裏面嗎?你已經在使用設計模式了好不好?
定義:
定義一個操作中的算法框架,而將一些步驟延遲到子類中實現,使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟。
要點:
抽象模板:定義模板結構,讓子類具體實現;
具體模板:具體實現抽象類的抽象方法。
場景:
將一些複雜的算法進行分割,將其算法中固定不變的部分設計爲模板方法和父類具體方法,而將一些可以改變的細節由其子類來實現;
各子類中公共的行爲應被提取出來並集中到一個公共父類中以避免代碼重複;
需要通過子類來決定父類算法中某個步驟是否執行,實現子類對父類的反響控制(鉤子)。
優缺點:
優點:
1.1代碼複用,相同部分代碼都放在抽象的父類中;
1.2.父類控制方法,子類負責實現,良好的擴展性;
1.3.反向控制,通過父類調用子類的操作,通過子類的擴展添加新的行爲。
缺點:
代碼的閱讀難度會增加,我們習慣性認爲抽象類聲明的都是最抽象的、最一般的事物屬性和方法,實現類完成 * 具體事物屬性和方法;而在模板方法模式中,抽象類中定義了部分抽象方法,而子類實現父類方法後執行的結果影響了父類, * 子類對父類產生了影響。
代碼演示:
1. 抽象父類
/*
* 以煮麪爲例子
*/
public abstract class CookNoodles {
//聲明稱final防止被重寫覆蓋
public final void cookNoodles() {
heatUpWater();
putNoodles2Water();
if (isNeedSeasoning()) {
putSeasoning();
}
}
/**
* 燒水是煮麪必須的步驟,這是唯一的,可以確定的,就可以在父類中進行實現,沒有必要交給子類
*/
private void heatUpWater() {
System.out.println("咕嘟嘟,水燒好了");
};
/**
* 把面放入沸水中,有的喜歡紅燒牛肉麪,有的喜歡老壇酸菜,有的喜歡掛麪,既然這麼不確定交給子類來實現吧
*/
protected abstract void putNoodles2Water();
/**
* 默認放調料,不想要你可以複寫isNeedSeasoning方法提出來
*/
protected void putSeasoning() {
System.out.println("加一波南德調料,巴適得很");
};
/**有的口味重,有的口味淡,調料不是必須放的,提供一個hook,自己覺得放不放
* 鉤子方法
*
* 判斷是否需要放調料。默認true要放
* @return
*/
protected boolean isNeedSeasoning() {
return true;
}
}
2. 子類1:
/**
* 吃掛麪,放調料
* @author Administrator
*
*/
public class GuaMian extends CookNoodles {
@Override
protected void putNoodles2Water() {
System.out.println("掛麪來一斤");
}
}
3. 子類2:
/**
* 來碗紅燒牛肉麪,默認要調料
* @author Administrator
*
*/
public class HongShao extends CookNoodles{
@Override
protected void putNoodles2Water() {
System.out.println("放入紅燒牛肉麪");
}
}
4. 子類3:
/**
* 來一碗老壇酸菜面,提出不要放調料,就喜歡酸菜的本味
* @author Administrator
*
*/
public class SuanCai extends CookNoodles{
@Override
protected void putNoodles2Water() {
System.out.println("放入老壇酸菜");
}
/**
* 不放調料,返回false
*/
@Override
protected boolean isNeedSeasoning() {
return false;
}
}
5. 測試類:
public class TestDemo {
public static void main(String[] args) {
new HongShao().cookNoodles();
System.out.println("--------------------");
new SuanCai().cookNoodles();
System.out.println("--------------------");
new GuaMian().cookNoodles();
}
}
6. 執行結果:
咕嘟嘟,水燒好了
放入紅燒牛肉麪
加一波南德調料,巴適得很
--------------------
咕嘟嘟,水燒好了
放入老壇酸菜
--------------------
咕嘟嘟,水燒好了
掛麪來一斤
加一波南德調料,巴適得很