Java通俗易懂系列設(shè)計(jì)模式之模板模式
實(shí)際開發(fā)中常常會(huì)遇到,代碼骨架類似甚至相同,只是具體的實(shí)現(xiàn)不一樣的場(chǎng)景。例如:流程都有開啟、編輯、駁回、結(jié)束。每個(gè)流程都包含這幾個(gè)步驟,不同的是不同的流程實(shí)例它們的內(nèi)容不一樣。共享單車都是先開鎖、騎行、上鎖、付款。這些大的步驟固定,不同的是每個(gè)實(shí)例的具體實(shí)現(xiàn)細(xì)節(jié)不一樣。這些類似的業(yè)務(wù)我們都可以使用模板模式實(shí)現(xiàn)。為什么要使用模板模式以及如何使用呢?
介紹定義:在模板模式(Template Pattern)中,一個(gè)抽象類公開定義了執(zhí)行它的方法的方式/模板。它的子類可以按需要重寫方法實(shí)現(xiàn),但調(diào)用將以抽象類中定義的方式進(jìn)行。這種類型的設(shè)計(jì)模式屬于行為型模式。
意圖:定義一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟
主要解決:一些方法通用,卻在每一個(gè)子類都重新寫了這一方法。 何時(shí)使用:有一些通用的方法。 如何解決:將這些通用算法抽象出來。 關(guān)鍵代碼:在抽象類實(shí)現(xiàn),其他步驟在子類實(shí)現(xiàn)。實(shí)現(xiàn)我們以生活中買菜做飯的例子來寫個(gè)Demo,燒飯一般都是買菜、洗菜、烹飪、裝盤四大過程。中國(guó)自古有八大菜系,制作方式肯定都避不開這四個(gè)過程。那在模板模式中如何實(shí)現(xiàn)呢?創(chuàng)建一個(gè)抽象類,它的模板方法被設(shè)置為 final。為防止惡意操作,一般模板方法都加上 final 關(guān)鍵詞。
public abstract class AbstractCookingService { //買菜 protected abstract void shopping(); //清洗 protected abstract void wash(); //烹飪 protected abstract void cooking(); //裝盤 protected abstract void dishedUp(); public final void process() {shopping();wash();cooking();dishedUp(); }}
創(chuàng)建實(shí)現(xiàn)了上述抽象類的子類。// 徽菜烹飪
/** * 徽菜制作大廚 */public class HuiCaiChef extends AbstractCookingService { @Override protected void shopping() {System.out.println('買菜:新鮮魚一條,紅辣椒五兩'); } @Override protected void wash() {System.out.println('清洗:紅椒洗凈切片,魚頭半分'); } @Override protected void cooking() {System.out.println('烹飪:魚頭水蒸,辣椒過油'); } @Override protected void dishedUp() {System.out.println('裝盤:用長(zhǎng)形盤子裝盛'); }}
// 川菜烹制
/** * 川菜制作大廚 */public class HuiCaiChef extends AbstractCookingService { @Override protected void shopping() {System.out.println('買菜:黑豬肉一斤,蒜頭5個(gè)'); } @Override protected void wash() {System.out.println('清洗:豬肉洗凈,蒜頭去皮'); } @Override protected void cooking() {System.out.println('烹飪:大火翻炒,慢火悶油'); } @Override protected void dishedUp() {System.out.println('裝盤:深碗盛起,熱油澆拌'); }}
使用 TemplatePatternDemo 類執(zhí)行模板方法 process() 來演示烹飪的定義方式。
public class TemplatePatternDemo { public static void main(String[] args) {System.out.println('----------川菜制作------------');AbstractCookingService chuanCaiService = new ChuanCaiChef();chuanCaiService.process();System.out.println('-----------徽菜制作-----------');AbstractCookingService huiCaiService = new HuiCaiChef();huiCaiService.process(); }}
執(zhí)行程序,輸出結(jié)果:
----------川菜制作------------
買菜:新鮮魚一條,紅辣椒五兩
清洗:紅椒洗凈切片,魚頭半分
烹飪:魚頭水蒸,辣椒過油
裝盤:用長(zhǎng)形盤子裝盛
-----------徽菜制作-----------
買菜:黑豬肉一斤,蒜頭5個(gè)
清洗:豬肉洗凈,蒜頭去皮
烹飪:大火翻炒,慢火悶油
從以上實(shí)例可以看出,其實(shí)模板模式也沒什么高深莫測(cè)的,簡(jiǎn)單來說就是三大步驟:
創(chuàng)建一個(gè)抽象類,定義幾個(gè)抽象方法和一個(gè)final修飾的模板方法,而模板方法中設(shè)定了抽象方法的執(zhí)行順序或邏輯。 無論子類有多少個(gè),只需要繼承該抽象類,實(shí)現(xiàn)父類的抽象方法重寫自己的業(yè)務(wù)。 根據(jù)不同的需求創(chuàng)建不同的子類實(shí)現(xiàn),每次調(diào)用的地方只需調(diào)用模板方法,即可完成特定的模板流程。總結(jié)從以上的分析和Demo我們可以看到,模板方法提高了我們的代碼的可維護(hù)性和可擴(kuò)展性。有優(yōu)點(diǎn)也有缺點(diǎn)。優(yōu)點(diǎn):
封裝不變部分,擴(kuò)展可變部分。 提取公共代碼,便于維護(hù)。 行為由父類控制,子類實(shí)現(xiàn)。缺點(diǎn):
每一個(gè)不同的實(shí)現(xiàn)都需要一個(gè)子類來實(shí)現(xiàn),導(dǎo)致類的個(gè)數(shù)增加,使得系統(tǒng)更加龐大。
使用場(chǎng)景:
有多個(gè)子類共有的方法,且邏輯相同。 重要的、復(fù)雜的方法,可以考慮作為模板方法。以上就是Java通俗易懂系列設(shè)計(jì)模式之模板模式的詳細(xì)內(nèi)容,更多關(guān)于Java設(shè)計(jì)模式的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. idea刪除項(xiàng)目的操作方法2. IntelliJ IDEA設(shè)置默認(rèn)瀏覽器的方法3. IntelliJ IDEA恢復(fù)刪除文件的方法4. 使用Maven 搭建 Spring MVC 本地部署Tomcat的詳細(xì)教程5. IntelliJ IDEA導(dǎo)入jar包的方法6. IntelliJ IDEA設(shè)置自動(dòng)提示功能快捷鍵的方法7. idea重置默認(rèn)配置的方法步驟8. Docker 部署 Prometheus的安裝詳細(xì)教程9. idea導(dǎo)入maven項(xiàng)目的方法10. IntelliJ IDEA調(diào)整字體大小的方法

網(wǎng)公網(wǎng)安備