一、模板模式的應用場景
模板模式又叫模板方法模式(Template Method Pattern),指定義一個算法的骨架,並允許自雷為一個或者多個步驟提供實現。模板模式使得子類可以在不改變算法結果的情況下,重新定義算法的某些步驟,屬於行為型設計模式。模板模式適用於以下場景:
- 一次性實現一個算法的不變部分,並將可變的行為留給子類來實現。
- 各子類中公共的行為被提取出來並集中到一個公共的父類中,從而避免代碼重復。
把東西裝冰箱的步驟模板:
public abstract class PutThingIntoFrigCourse { protected final void createCourse() { //是否需要對大塊的東西進行切割 if (needCut()) { this.cut(); } //打開冰箱門 this.openDoor(); //把東西放進去 this.putThingIntoFrig(); //關閉冰箱門 this.closeDoor(); } //鈎子方法:對步驟進行微調 protected boolean needCut() { return false; } //鈎子方法:就是通過返回值對模板類內部進行修改 abstract String thing(); final void cut() { System.out.println("切碎" + thing()); } final void openDoor() { System.out.println("打開冰箱門"); } final void putThingIntoFrig() { System.out.println("把" + thing() + "放冰箱"); } final void closeDoor() { System.out.println("關閉冰箱門"); } }
這里面的鈎子方法主要目的是干預執行流程,使得控制行為更加靈活,更符合實際業務需求,鈎子方法通過返回值對主流程進行控制。
二、模板模式在源碼中的體現
JDBCTemplate看這個名字就知道了。再看JDK中的AbstractList類的代碼:
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> { ... abstract public E get(int index); ... }
可以發現get()方法是一個抽象方法,交給子類實現,比如ArrayList就是AbstractList的子類。還有HttpServlet,有三個方法:service()、doGet()、doPost() 都是模板方法的抽象實現。
在Mybatis框架中有一個BaseExecutor類,它是一個基礎的sql執行類,實現了大部分SQL的執行邏輯,然后把幾個方法交給子類定制化完成。
三、模板模式的優缺點
優點:
- 利用模板模式將相同處理邏輯的代碼放在抽象父類中,可以提高代碼的復用性。
- 將不同的代碼放到不同的子類中,通過對子類的擴展增加新的行為,可以提高代碼的擴展性。
- 把不變的行為卸載父類中,除去子類的重復代碼,提供了一個很好的代碼復用平台,符合開閉原則。
缺點:
- 每個抽象類都需要一個子類實現,導致類的數量增加。
- 類數量的增加間接的增加了系統復雜性。
- 因為繼承關系自身的缺點,如果父類添加新的抽象方法,所有子類都要改一遍。