模板方法模式

2021-07-28 19:46:55 字數 3316 閱讀 5174

定義乙個操作中的演算法的框架,而將一些步驟延遲到子類中。使得子類可以不改變乙個演算法的結構可重定義改演算法的某些特定步驟(通俗理解:將方法的實現延遲到子類)

多個子類有公有的方法,並且邏輯基本相同

重要、複雜的演算法,可以把核心演算法設計為模版方法,周邊的相關細節功能則由各個子類實現

重構時,模板方法模式是乙個經常使用的模式,把相同的**抽取到父類中,然後通過鉤子函式(見下文解釋)約束其行為

宣告抽象父類,抽象公有方法

延遲到子類實現抽象方法

通過鉤子函式約束父親行為(可選)

/**

* created by zs on 2017/3/17.

* * 抽象模板類

*/public

abstract

class

abstractclass

}/**

* created by zs on 2017/3/17.

* * 具體模板類

*/public

class

concreteclass1

extends

abstractclass

@override

protected

void

doanything()

}/**

* created by zs on 2017/3/17.

* * 具體模板類

*/public

class

concreteclass2

extends

abstractclass

@override

protected

void

doanything()

}/**

* created by zs on 2017/3/17.

* * 場景類

*/public

class

client

}

抽象模板中的基本方法盡量設計為protected型別,符合迪公尺特法則(請看下文),不需要暴露的屬性和方法盡量不要設定為protected型別,實現類若非必要,盡量不要擴大父類中的訪問許可權

那麼什麼是迪公尺特法則(lod)呢:

通俗理解:乙個類應該對自己需要耦合或呼叫的類知道的最少,你(被耦合或呼叫的類)的內部是如何複雜都和我沒關係,那是你的事情,我就知道你提供的這麼多的public 方法,我就呼叫這麼多,其他的我一概不關係。

解釋分析:

1. 只和朋友交流 乙個類只和朋友交流,不與陌生類交流

2. 朋友間也是有距離的,迪公尺特法則要求類 「羞澀」 一點,盡量不要對外公布太多的public方法和非靜態的public變數,盡量內斂

3. 是自己的就是自己的,如果乙個方法放在本類中,既不增加類間關係,也對本類不產生負面影響,那就放在本類中

問題:父類的模板方法約定了基本方法(父類抽象方法)的執行,但是子類無法私人訂製是否要執行某乙個基本方法?

解決方案:鉤子方法

鉤子方法:影響模板方法執行結果的方法

一言不合上**:

/**

* created by zs on 2017/3/17.

* * 抽象模板類

*/public

abstract

class

abstractclass

//模板方法

public

void

templatemethod()

}}/**

* created by zs on 2017/3/17.

* * 具體模板類

*/public

class

concreteclass1

extends

abstractclass

@override

protected

void

doanything()

@override

protected

boolean

i***ecutesomething()

}/**

* created by zs on 2017/3/17.

* * 具體模板類

*/public

class

concreteclass2

extends

abstractclass

@override

protected

void

doanything()

}

問題:父類怎麼呼叫子類的方法?能?不能?

回答:能

解決方案:

1. 把子類傳遞到父類的有參構造中,然後呼叫

2. 使用反射的方式呼叫(你使用了反射還有誰不能差遣的,還有誰……還有誰……)

3. 父類呼叫子類的靜態方法

自嘲:這三種方法都是直接呼叫子類的方法,專案中允許使用嗎?不允許!為什麼要用父類呼叫子類的方法,如果一定要呼叫子類,那為什麼要繼承它呢?

換個姿勢:父類建立框架,子類重寫了父類部分的方法後,再呼叫父類繼承的方法,產生不同的結果,這一修改子類,影響父類的行為,曲線救國的方式實現了父親依賴子類的場景。

一言不合再上**:

/**

* created by zs on 2017/3/17.

* * 抽象模板類

*/public

abstract

class

abstractclass

}/**

* created by zs on 2017/3/17.

* * 具體模板類

*/public

class

concreteclass1

extends

abstractclass

@override

protected

void

doanything()

//子類方法

private

void

sonmethod()

}

優點:1. 封裝不變部分,擴充套件可變部分

2. 提取公共部分**,便於維護

3. 行為由父類控制,子類實現

缺點:

子類執行的結果影響了父類的結果,也就是子類產生了影響,這在複雜的專案中,會帶來**閱讀的難度

模板方法模式

有這樣乙個場景 乙個演算法或流程,它的步驟以及步驟之間的順序是固定的,但具體的某一步可能有不同的實現。對於這麼乙個場景,可以建立多個類,各個類實現不同的實現,但是這樣的缺點是 易錯 難改,易錯 應為步驟和順序是固定的,而且在每個類中都要寫一遍,程式設計師怎有心情不好的時候,就有可能把其中某一步給寫錯...

模板方法模式

模板方法模式 定義乙個演算法框架,將裡面的操作步驟推遲到子類中去執行,這樣使得子類不用改變框架,只需改變某些操作步驟方法 ifndef test h define test h include include using namespace std class test virtual test v...

模板方法模式

模板方法模式 在乙個方法中定義乙個演算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以在不改變演算法結構的情況下,重新定義演算法的某些步驟。還可以使用鉤子對可選部分進行判斷。include include using namespace std class caffeinebeverage ...