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):定義一個(gè)操作中的算法的框架, 而將一些步驟延遲到子類中。使得子類可以不改 變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟。
說人話:父類模板方法定義不變的流程,子類重寫流程中的方法。
2、模板模式定義
①、AbstractClass 抽象模板
一、基本方法
上面的 baseOperation() 或者 customOperation() 方法,也叫基本操作,是由子類實(shí)現(xiàn)的方法,并且在模板方法中被調(diào)用。
基本方法盡量設(shè)計(jì)為protected類型, 符合迪米特法則, 不需要暴露的屬性或方法盡量不要設(shè)置為protected類型。實(shí)現(xiàn)類若非必要, 盡量不要擴(kuò)大父類中的訪權(quán)限。
二、模板方法
上面的 templateMethod() 方法,可以有一個(gè)或者幾個(gè),實(shí)現(xiàn)對(duì)基本方法的調(diào)度,完成固定的邏輯。
為了防止惡意操作,通常模板方法都加上 final 關(guān)鍵字,不允許覆寫。
②、ConcreteClass 具體模板
實(shí)現(xiàn)父類定義的一個(gè)或多個(gè)抽象方法,也就是父類定義的基本方法在子類中得以實(shí)現(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()");
}
}
測(cè)試:
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)點(diǎn)
①、封裝不變部分, 擴(kuò)展可變部分
把認(rèn)為是不變部分的算法封裝到父類實(shí)現(xiàn), 而可變部分的則可以通過繼承來繼續(xù)擴(kuò)展。
②、提取公共部分代碼, 便于維護(hù)
③、行為由父類控制, 子類實(shí)現(xiàn)
基本方法是由子類實(shí)現(xiàn)的, 因此子類可以通過擴(kuò)展的方式增加相應(yīng)的功能, 符合開閉原則。
5、模板模式缺點(diǎn)
①、子類執(zhí)行的結(jié)果影響了父類的結(jié)果,這和我們平時(shí)設(shè)計(jì)習(xí)慣顛倒了,在復(fù)雜項(xiàng)目中,會(huì)帶來閱讀上的難度。
②、可能引起子類泛濫和為了繼承而繼承的問題
6、回調(diào)
為了解決模板模式的缺點(diǎn),我們可以利用回調(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();
}
}
測(cè)試:
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是一個(gè)穩(wěn)定的final類,無法被繼承,不存在子類行為影響父類結(jié)果的問題,而Callback是一個(gè)接口,為了繼承而繼承的問題消失了。
-
封裝
+關(guān)注
關(guān)注
126文章
7873瀏覽量
142893 -
模板
+關(guān)注
關(guān)注
0文章
108瀏覽量
20560 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4327瀏覽量
62569 -
代碼
+關(guān)注
關(guān)注
30文章
4779瀏覽量
68521
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論