模版方法模式

一、模版方法模式定义和特点

在Spring源码中该设计模式被频繁引用,所以在看Spring源码时通常是绕来绕去,想找到业务实际的执行代码需要熟悉整体的继承结构。有些通用的内容父类进行封装,多变的内容定义成钩子方法,由继承的子类来实现。
模板方法(Template Method)模式的定义:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤,它是一种类行为型模式。

该模式的主要优点

1.对不变部分内容进行封装,提供钩子方法方便于子类扩展可变部分。
2.由于父类定义了公共的代码部分,有利于代码复用。
3.父类整体流程中对某一部分是由子类实现的,故子类可以通过扩展方式增加相应的功能,符合开闭原则。

该模式的主要缺点

1.对每个不同的业务实现都需要定义一个子类,这会导致项目中Java类的个数增加,系统显得更厚重,设计看起来很抽象。
2.父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,属于类的反向的控制结构,提高了代码阅读的难度。

二、模版方法模式的结构和实现

模版方法模式的结构需要父类和子类配合完成,父类定义通用的代码片段,如一个面板具体的绘制工作流程由父类来决定,制定一个详细的面板内容钩子方法,该方法需要子类来具体实现。所以通过继承创建的多个子类在绘画的过程中内容都是迥然不同的。

模板方法模式包含以下内容

抽象类(Abstract Class):负责给出一个算法的轮廓和骨架(pipline)。它由一个模板方法和若干个基本方法构成,这些方法的定义如下。
模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。
基本方法:是整个算法中的一个步骤,包含以下几种类型。
1.抽象方法:在抽象类中申明,由具体子类实现。
2.具体方法:在抽象类中已经实现,在具体子类中可以继承或重写它。
3.钩子方法:在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。
具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的一个组成步骤。

三、模版方法的案例

public interface Drawing {
    void draw();
}
/**
 * 绘画中心
 */
public abstract class AbstractDrawingCenter implements Drawing {

    /**
     * 模版方法流程
     */
    @Override
    public void draw() {

        Brush brush = createBrushInstance();

        DrawPanel drawPanel = createDrawPanelInstance();

        Pigment pigment = createPigmentInstance();

        Painter painter = createPainterInstance();

        painter.draw(brush, drawPanel, pigment);
    }

    /**
     * 钩子方法子类自定义实现
     */
    abstract public Brush createBrushInstance();

    abstract public DrawPanel createDrawPanelInstance();

    abstract public Pigment createPigmentInstance();

    abstract public Painter createPainterInstance();
}
@Data
@AllArgsConstructor
public class Pigment {
    private String name;
}
@Data
@AllArgsConstructor
public class Painter {
    private static final Logger LOGGER = LoggerFactory.getLogger(Painter.class);
    private String name;
    public void draw(Brush brush, DrawPanel panel, Pigment pigment) {
        LOGGER.info("画家【{}】绘画开始,使用【{},{},{}】这些工具开始他的创作之旅!", JSON.toJSONString(name), JSON.toJSONString(brush), JSON.toJSONString(panel), JSON.toJSONString(pigment));
    }
}
@Data
@AllArgsConstructor
public class DrawPanel {
    private String name;
}
@Data
@AllArgsConstructor
public class Brush {
    private String name;
}
/**
 * 自定义绘画中心,配置了专业的画家和各种不错的绘画工具。
 */
@Service("testDrawingCenter")
public class TestDrawingCenter extends AbstractDrawingCenter implements Drawing {

    @Override
    public Brush createBrushInstance() {
        return new Brush("狼毫毛刷");
    }

    @Override
    public DrawPanel createDrawPanelInstance() {
        return new DrawPanel("宽大的画板");
    }

    @Override
    public Pigment createPigmentInstance() {
        return new Pigment("五彩缤纷的颜料");
    }

    @Override
    public Painter createPainterInstance() {
        return new Painter("专业的画家");
    }
}

案例主要是有一个模版流程的方法draw(),该方法先获取画笔,画板,颜料,聘请画家进行绘画。定义的钩子方法可以让子类自定义实现,可扩展性很强,但是模版方法过深会影响可读性。

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