博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript设计模式之模板方法模式
阅读量:5891 次
发布时间:2019-06-19

本文共 3534 字,大约阅读时间需要 11 分钟。

前言:菜鸡也有梦想,而我的梦想就是进一个真正的互联网大厂。以前学习的时候没有系统的整理,从今天开始要保持每周写博客的习惯,希望自己可以有所成长。为了培养编程思维,决定从设计模式开始写起。我是通过读《Javascript设计模式与开发实践》来学习设计模式,并且将知识点和收获记录在博客中。

此文仅记录本人阅读《JavaScript设计模式与开发实践》的知识点与想法,感谢作者曾探大大写出这么好的一本书。如有冒犯,请联系本人:markcoder@outlook.com处理,请大家购买正版书籍。

1.模板方法模式介绍

模板方法模式由两部分结构组成,第一部分是抽象父类,第二部分是具体的实现子类。通常 在抽象父类中封装了子类的算法框架,包括实现一些公共方法以及封装子类中所有方法的执行顺 序。子类通过继承这个抽象类,也继承了整个算法结构,并且可以选择重写父类的方法。

假如我们有一些平行的子类,各个子类之间有一些相同的行为,也有一些不同的行为。如果相同和不同的行为都混合在各个子类的实现中,说明这些相同的行为会在各个子类中重复出现。但实际上,相同的行为可以被搬移到另外一个单一的地方,模板方法模式就是为解决这个问题而生的。在模板方法模式中,子类实现中的相同部分被上移到父类中,而将不同的部分留待子类来实现。这也很好地体现了泛化的思想。

2.代码实现

书中有一个非常好的例子。

首先,我们先来泡一杯咖啡,如果没有什么太个性化的需求,泡咖啡的步骤通常如下:

(1) 把水煮沸

(2) 用沸水冲泡咖啡

(3) 把咖啡倒进杯子

(4) 加糖和牛奶

通过下面这段代码我们就能得到一杯香浓的咖啡:

class Coffee {    constructor () {        this.init = () => {            this.boilWater();             this.brewCoffeeGriends();             this.pourInCup();             this.addSugarAndMilk();        }    }        boilWater () {        console.log('把水煮沸');    }        brewCoffeeGriends () {        console.log('用沸水冲泡咖啡');    }        pourInCup () {        console.log('把咖啡倒进杯子');    }        addSugarAndMilk () {        console.log('加糖和牛奶');    }}复制代码

接下来,开始准备我们的茶,泡茶的步骤跟泡咖啡的步骤相差并不大:

(1) 把水煮沸

(2) 用沸水浸泡茶叶

(3) 把茶水倒进杯子

(4) 加柠檬

同样用一段代码来实现泡茶的步骤:

class Tea {    constructor () {        this.init = () => {            this.boilWater();             this.steepTeaBag();             this.pourInCup();             this.addLemon();        }    }        boilWater () {         console.log( '把水煮沸' );     }        steepTeaBag () {         console.log( '用沸水浸泡茶叶' );     }        pourInCup () {        console.log( '把茶水倒进杯子' );     }        addLemon () {         console.log( '加柠檬' );     }}复制代码

观察可以发现,原料不同。一个是咖啡,一个是茶,但我们可以把它们都抽象为“饮料”。泡的方式不同。咖啡是冲泡,而茶叶是浸泡,我们可以把它们都抽象为“泡”加入的调料不同。一个是糖和牛奶一个是柠檬但我们可以把它们都抽象为“调料”。

如果有的客户不喜欢加调料,我们还可以通过钩子方法来解决问题。

class Beverage {    constructor () {        this.init = () => {            this.boilWater();             this.brew();             this.pourInCup();             if (this.customerWantsCondiments()) { // 钩子方法,只有返回true,才执行                this.addCondiments();            }        }    }        boilWater () {        console.log('把水煮沸')    }        brew () {        throw new Error( '子类必须重写 brew 方法' );    }        pourInCup () {        throw new Error( '子类必须重写 pourInCup 方法' );    }        addCondiments () {        throw new Error( '子类必须重写 addCondiments 方法' );    }        customerWantsCondiments () {        return true; // 默认返回true    }}class Tea extends Beverage {    constructor (...args) {        super(...args)    }        brew () {        console.log( '用沸水浸泡茶叶' );     }        pourInCup () {        console.log( '把茶水倒进杯子' );     }        addCondiments () {        console.log( '加柠檬' );     }        customerWantsCondiments () {        return false;    }}let tea = new Tea();tea.init();class Coffee extends Beverage {    constructor (...args) {        super(...args)    }        brew () {        console.log( '用沸水冲泡咖啡' );     }        pourInCup () {        console.log( '把咖啡倒进杯子' );     }        addCondiments () {        console.log( '加糖和牛奶' );     }}let coffee = new Coffee();coffee.init();复制代码

3.适用场景

在 Web 开发中也能找到很多模板方法模式的适用场景,比如我们在构建一系列的 UI 组件, 这些组件的构建过程一般如下所示:

(1) 初始化一个 div 容器;

(2) 通过 ajax 请求拉取相应的数据;

(3) 把数据渲染到 div 容器里面,完成组件的构造;

(4) 通知用户组件渲染完毕。

我们看到,任何组件的构建都遵循上面的 4 步,其中第(1)步和第(4)步是相同的。第(2)步不 同的地方只是请求 ajax 的远程地址,第(3)步不同的地方是渲染数据的方式。 于是我们可以把这 4 个步骤都抽象到父类的模板方法里面,父类中还可以顺便提供第(1)步和 第(4)步的具体实现。当子类继承这个父类之后,会重写模板方法里面的第(2)步和第(3)步。

参考

《JavaScript设计模式与开发实践》—— 曾探

转载于:https://juejin.im/post/5cc29f995188250aa35bb6e4

你可能感兴趣的文章
[python] 初学python,打卡签到
查看>>
向coconut致敬
查看>>
oracle 循环
查看>>
Android studio恢复代码
查看>>
模板引擎Nvelocity实例
查看>>
Sinfonia: a new paradigm for building scalable distributed systems(翻译)
查看>>
Codeforces Round #223 (Div. 2)
查看>>
去除字符串中的html标记及标记中的内容
查看>>
Fibonacci数列--矩阵乘法优化
查看>>
书籍推荐-记这几年看的书
查看>>
JAVA编程思想第二章读书笔记
查看>>
Centos网络时好时超时问题解决
查看>>
C语言 控制台程序生成BMP图片
查看>>
ROS系统MoveIt玩转双臂机器人系列(六)--D-H逆运动学求解程序(C++)
查看>>
Hive参数配置调优
查看>>
ettercap+arpspoof进行HTTP信息嗅探
查看>>
IIS注册NET FRAMEWORK语句
查看>>
Android 手机上获取物理唯一标识码[转]
查看>>
软件的增量更新
查看>>
robotframework关于To Json问题
查看>>