1、什么是模板模式?
Define the skeleton of an algorithm in an operation, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithm’s structure.
模板方法模式(Template Method Pattern):定義一個操作中的算法的框架, 而將一些步驟延遲到子類中。使得子類可以不改 變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
說人話:父類模板方法定義不變的流程,子類重寫流程中的方法。
2、模板模式定義
①、AbstractClass 抽象模板
一、基本方法
上面的 baseOperation() 或者 customOperation() 方法,也叫基本操作,是由子類實現(xiàn)的方法,并且在模板方法中被調(diào)用。
基本方法盡量設(shè)計為protected類型, 符合迪米特法則, 不需要暴露的屬性或方法盡量不要設(shè)置為protected類型。實現(xiàn)類若非必要, 盡量不要擴大父類中的訪權(quán)限。
二、模板方法
上面的 templateMethod() 方法,可以有一個或者幾個,實現(xiàn)對基本方法的調(diào)度,完成固定的邏輯。
為了防止惡意操作,通常模板方法都加上 final 關(guān)鍵字,不允許覆寫。
②、ConcreteClass 具體模板
實現(xiàn)父類定義的一個或多個抽象方法,也就是父類定義的基本方法在子類中得以實現(xiàn)。
3、模板模式通用代碼
public abstract class AbstractClass {
// 共同的且繁瑣的操作
private void baseOperation() {
// do something
}
// 由子類定制的操作
protected abstract void customOperation();
// 模板方法定義的框架
public final void templateMethod() {
/**
* 調(diào)用基本方法,完成固定邏輯
*/
baseOperation();
customOperation();
}
}
public class ConcreteClass1 extends AbstractClass{
@Override
protected void customOperation() {
// 具體模板1 業(yè)務(wù)邏輯
System.out.println("具體模板1:customOperation()");
}
}
public class ConcreteClass2 extends AbstractClass{
@Override
protected void customOperation() {
// 具體模板2 業(yè)務(wù)邏輯
System.out.println("具體模板2:customOperation()");
}
}
測試:
public class TemplateClient {
public static void main(String[] args) {
AbstractClass abstractClass1 = new ConcreteClass1();
AbstractClass abstractClass2 = new ConcreteClass2();
applyTemplate(abstractClass1);
applyTemplate(abstractClass2);
}
public static void applyTemplate(AbstractClass abstractClass){
abstractClass.templateMethod();
}
}
4、模板模式優(yōu)點
①、封裝不變部分, 擴展可變部分
把認(rèn)為是不變部分的算法封裝到父類實現(xiàn), 而可變部分的則可以通過繼承來繼續(xù)擴展。
②、提取公共部分代碼, 便于維護(hù)
③、行為由父類控制, 子類實現(xiàn)
基本方法是由子類實現(xiàn)的, 因此子類可以通過擴展的方式增加相應(yīng)的功能, 符合開閉原則。
5、模板模式缺點
①、子類執(zhí)行的結(jié)果影響了父類的結(jié)果,這和我們平時設(shè)計習(xí)慣顛倒了,在復(fù)雜項目中,會帶來閱讀上的難度。
②、可能引起子類泛濫和為了繼承而繼承的問題
6、回調(diào)
為了解決模板模式的缺點,我們可以利用回調(diào)函數(shù)代替子類繼承。
public interface Callback {
void customOperation();
}
public class SubCallback implements Callback{
@Override
public void customOperation() {
System.out.println("SubCallback customOperation");
}
}
/**
* 模板類
* 聲明為 final,無法被繼承
*/
public final class Template {
private void baseOperation(){
System.out.println("模板類公共操作");
}
public void templateMethod(Callback callback){
baseOperation();
callback.customOperation();
}
}
測試:
public class TemplateClient {
public static void main(String[] args) {
Template template = new Template();
applyTemplate(template);
}
public static void applyTemplate(Template template){
Callback callback = new SubCallback();
template.templateMethod(callback);
}
}
Template是一個穩(wěn)定的final類,無法被繼承,不存在子類行為影響父類結(jié)果的問題,而Callback是一個接口,為了繼承而繼承的問題消失了。
-
封裝
+關(guān)注
關(guān)注
128文章
8618瀏覽量
145137 -
模板
+關(guān)注
關(guān)注
0文章
109瀏覽量
20849 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4377瀏覽量
64556 -
代碼
+關(guān)注
關(guān)注
30文章
4894瀏覽量
70452
發(fā)布評論請先 登錄
改善代碼質(zhì)量的6種重構(gòu)模式
為什么要重構(gòu)?如何重組Python包?
基于ATmega162的自重構(gòu)機器人控制模式
模板方法模式在回溯算法中的應(yīng)用
模板方法模式在回溯算法中的應(yīng)用
一種基于體系結(jié)構(gòu)模板的粗粒度可重構(gòu)SoC設(shè)計方法

使用英特爾SIMD數(shù)據(jù)布局模板提高矢量化效率
HarmonyOS如何自動生成JS FA調(diào)用Java PA的模板代碼
SOC課程——③——Verilog程序(典型電路的模板)

在重構(gòu)或重新設(shè)計時驗證代碼
如何借助GPT-4評審、重構(gòu)代碼?
代碼重構(gòu)的經(jīng)驗總結(jié)

「重構(gòu):改善既有代碼的設(shè)計」實戰(zhàn)篇

評論