模板方法模式(Template Method)

1.介绍

1.1定义

  • 模板方法模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式的用意。

比如定义一个操作中的算法的骨架,将步骤延迟到子类中。模板方法使得子类能够不去改变一个算法的结构即可重定义算法的某些特定步骤。

1.2 主要作用

在不改变模板结构的前提下在子类中重新定义模板中的内容。

模板方法模式是基于”继承“的。

1.3 解决的问题

  • 提高代码复用性:将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。
  • 实现了反向控制:通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 & 符合“开闭原则”。

2. 模式原理

2.1 UML类图 & 组成讲解

模板方法模式UML.png
  • 抽象类(Abstract Class):实现了模板方法,定义了算法的骨架。
  • 具体类(Concrete Class):实现抽象类中的抽象方法,已完成完整的算法。

2.2 实例讲解

接下来我用一个实例来对模板方法模式进行更深一步的介绍。

a. 实例概况

  • 背景:小成希望学炒菜:手撕包菜 & 蒜蓉炒菜心
  • 冲突:两道菜的炒菜步骤有的重复有的却差异很大,记不住
  • 解决方案:利用代码记录下来

b. 使用步骤

步骤1:创建抽象模板结构(AbstractClass):炒菜的步骤

public abstract class AbstractClass {
    //模板方法,用来控制炒菜的流程 (炒菜的流程是一样的-复用)
    //申明为final,不希望子类覆盖这个方法,防止更改流程的执行顺序
    final void cookProcess(){
        //第一步:倒油
        this.pourOil();
        //第二步:热油
        this.HeatOil();
        //第三步:倒蔬菜
        this.pourVegetable();
        //第四步:倒调味料
        this.pourSauce();
        //第五步:翻炒
        this.fry();
    }

    //定义结构里哪些方法是所有过程都是一样的可复用的,哪些是需要子类进行实现的
    //第一步:倒油是一样的,所以直接实现
    void pourOil(){
        System.out.println("倒油");
    }
    //第二步:热油是一样的,所以直接实现
    void  HeatOil(){
        System.out.println("热油");
    }
    //第三步:倒蔬菜是不一样的(一个下包菜,一个是下菜心)
    //所以声明为抽象方法,具体由子类实现
    abstract void  pourVegetable();
    //第四步:倒调味料是不一样的(一个下辣椒,一个是下蒜蓉)
    //所以声明为抽象方法,具体由子类实现
    abstract void  pourSauce();
    //第五步:翻炒是一样的,所以直接实现
    void fry(){
        System.out.println("炒啊炒啊炒到熟啊");
        System.out.println("---------------------------------");
    };
}

步骤2:创建具体模板(ConcreteClass),手撕包菜(ConcreteClass_BaoCai)的具体步骤

//炒手撕包菜的类
public class ConcreteClass_BaoCai extends AbstractClass {
    @Override
    void pourVegetable() {
        System.out.println("下锅的蔬菜是包菜");
    }
    @Override
    void pourSauce() {
        System.out.println("下锅的酱料是辣椒");
    }
}

步骤3:创建具体模板(ConcreteClass),蒜蓉炒菜心(ConcreteClass_CaiXin)的具体步骤

//炒蒜蓉菜心的类
public class ConcreteClass_CaiXin extends AbstractClass {
    @Override
    void pourVegetable() {
        System.out.println("下锅的蔬菜是菜心");
    }
    @Override
    void pourSauce() {
        System.out.println("下锅的酱料是蒜蓉");
    }
}

步骤4:客户端调用-炒菜了

public class TemplateMethod {
    public static void main(String[] args){
        //炒 - 手撕包菜
        ConcreteClass_BaoCai BaoCai = new ConcreteClass_BaoCai();
        BaoCai.cookProcess();

        //炒 - 蒜蓉菜心
        ConcreteClass_CaiXin CaiXin = new ConcreteClass_CaiXin();
        CaiXin.cookProcess();
    }
}

输出结果

倒油
热油
下锅的蔬菜是包菜
下锅的酱料是辣椒
炒啊炒啊炒到熟啊
---------------------------------
倒油
热油
下锅的蔬菜是菜心
下锅的酱料是蒜蓉
炒啊炒啊炒到熟啊
---------------------------------

3. 优缺点

3.1 优点

  • 模板方法模式通过把不变的行为搬移到超类,去除了子类中的重复代码。
  • 子类实现算法的某些细节,有助于算法的扩展。
  • 通过一个父类调用子类实现的操作,通过子类扩展增加新的行为,实现了反向控制 &符合“开放-封闭原则”。

3.2 缺点

引入了抽象类,每一个不同的实现都需要一个子类来实现,导致类的个数增加,从而增加了实现的复杂度。

4. 应用场景

  • 一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。
  • 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
  • 控制子类的扩展,子类必须遵守算法规则。

5.感谢

模板方法模式(Template Method) - 最易懂的设计模式解析
Java设计模式之模板方法模式(Template Method)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容