模版模式:优雅、灵活地拓展你的pipeline

模版模式,作为一种行为型模式,通过在抽象类或接口中定义一个操作中的算法骨架,而将一些步骤具体执行延迟到子类中实现,从而使得父类的方法执行可以获得不一样的结果。从而达到了代码复用、扩展性好、灵活度高的设计目的。

使用时机

模版模式使用时机,主要是相同、相似方法使用较多的情况。采用模版模式,可以将这些相似的方法提取出来,制定出一个相对普适的模版,从而减少代码的重复书写,提高代码的复用率。抽象化的使用场景及实现逻辑如下图所示。

基本定义

在了解如何写模版模式之前,我们有必要来了解一些有关模版模式的关键名词及术语。

基本方法:

基本方法又可以划分为如下三类:

1、具体方法(Concrete Method)

具体方法指的是由父类/接口负责实现的方法,子类不可以对该方法进行更改。

2、抽象方法(Abstract Method)

抽象方法则指的是不由父类/接口实现具体步骤,而是将其具体操作步骤推迟到子类实现,从而对不同情况实现不同的操作。

3、钩子方法(Hook Method)

    一个钩子方法由抽象类声明并实现,而子类会加以扩展。**它是子类可以选择性实现或不实现的方法**,通常抽象类给出是一个空实现,作为方法的默认实现。

    这样的默认实现,被称为**默认钩子方法**。这种空钩子方法也叫做“Do Nothing Hook”。默认钩子方法在缺省适配模式也有相应的使用。缺省适配模式讲的是一个类为接口提供一个默认的空实现,从而使得子类不必给出所有方法的实现,因为通常一个具体类并不需要所有的方法。这个思想正好同默认钩子方法不谋而合。

    钩子方法常见的用途为,将两个存在不同调用关系的pipeLine流程,通过钩子方法联系到同一个模版中,从而屏蔽不同内容的差异性。但是,需要注意的一点是,**钩子方法的名字应当以do开始,这是熟悉设计模式的Java开发人员的标准做法。**如doScan、doGet等。

模版方法:

    模版方法是模版模式的核心点,其是定义在抽象类中的,是把基本操作方法组合在一起形成总的算法或行为的方法。一个抽象类可以有**任意多个模板方法**,而不限于一个。每一个模板方法都可以调用任意多个具体方法。原则上,**子类不可以、也不应该对模版方法进行覆盖或者重写**。

上述定义中各类方法的对应模块大致如下图所示:

代码实践

模版模式的实现,在java中有两种方式,一种是基于抽象类的实现方式,另外一种则是基于接口的实现方式

这里我们以抽象类的实现方法为例子介绍相应的模版模式的实现。

public abstract class Template {

    public void concreteMethod() {
        System.out.println("concreteMethod:");
    }

    public abstract void abstractMethod();

    public void hookMethod(){
        System.out.println("hookMethod:");
        System.out.println("实现默认hookMethod!");
    }


    public final void execute() {
        concreteMethod();

        abstractMethod();

        hookMethod();
    }
}

首先,定义出我们的模版接口,其中包含三个方法concreteMethod、abstractMethod、hookMethod。就分别对应于我们上述提到的具体方法、抽象方法及钩子方法

然后在execute()方法内,定义好三个方法的基本执行方法,同时采用final修饰符,使得子类无法修改execute方法中的执行顺序。

然后在我们的子类HerFuction中,首先必须要对抽象方法进行相应的实现。这里我们简单的输出类名。

而在钩子方法hookMethod中,我们则对原方法进行增强,多输出一句话:“我还要执行自己的hookMethod方法!”。

public class HerFunction implements Template {

    @Override
    public void abstractMethod() {
        System.out.println("HerFunciton !");
    }

    @Override
    public void hookMethod() {
        Template.super.hookMethod();
        System.out.println("我还要执行自己的hookMethod方法!");
    }
}

类似地,在第二个子类MyFunction中,我们也需要实现相应的抽象类方法。但对于钩子方法则采用默认的抽象类中的方法实现即可。

public class MyFunction extends Template {

    @Override
    public void abstractMethod() {
        System.out.println("My Function!");
    }
}

最后,在启动方法中分别创建MyFunction、HerFunction对应的对象,并调用父类的execute方法即可。

    public static void main(String[] args) {
        Template myFunction = new MyFunction();
        myFunction.execute();
        System.out.println("================我是分割线=========================");
        Template herFunction = new HerFunction();
        herFunction.execute();
    }

最后得到的结果如下:

可以看到,子类对concreteMethod方法都成功实现了复用,而对于abstractMethod则根据不同子类实现了不同的逻辑,体现了差异性。同时钩子方法的默认实现及子类实现,也体现了模版的灵活性。

优缺点分析

优点:

1、利用模板模式将相同处理逻辑的代码放到抽象父类中,可以提高代码的复用性。

2、将相同业务含义的处理代码放置到不同的子类中,通过对子类的扩展增加新的行为,从而提高代码的扩展性。

3、把不变的行为写在父类上,去除子类的重复代码,提供了一个很好的代码复用平台,符合开闭原则。

缺点:

1、模版模式的实现依赖于子类的构建,因此类的数量会存在明显的增加,增加了类的复杂度。

2、采用抽象类情况下,继承关系自身存在一定缺点,如果父类添加新的抽象方法,所有子类都要对该抽象方法进行实现。JAVA语言可以采用接口+default关键字的方式,一定程度上避免这个修改。(但是带来的副作用是不能采用final对方法进行限制)

参考文献

《JAVA设计模式》之模板模式(Template)

模版模式

详解Java8接口中引入default关键字的本质原因

模板模式的优缺点

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

推荐阅读更多精彩内容