模板方法模式基于继承?呵呵

明人不说暗话,我在看文章的时候,歪瑞讨厌看到诸如“继承”,“抽象类”,“父类子类爷爷类”之类的“非JS专用词汇”。恰巧模板方法模式上来就是一句:模板方法是一种基于继承的设计模式。后面还强调了一句:模板方法模式是一种只需使用继承就可以实现的非常简单的模式。对于不喜欢“继承”的我而言,还得去温习一下继承,为了写文章我去把ES6 class部分的语法过了一遍再看这一章,然后最气的事情发生了,看完之后我发现模板方法模式根本不需要继承

经典例子coffee or tea

看过原著的都知道,我这人从来不会按照书上的例子进行总结,因为书上的代码有点多,我懒得抄你也懒得看。我来举一个简单的例子,社畜。大家都知道,社畜的生活一般就是两点一线:家——公司,每天不是上班的路上就是回家的路上。下面建立一个社畜的模型(我用了es6里的class,其实就是obj.prototype.xxx的语法糖,看不懂的可以查阅coffee or tea的源代码)

	class Human{
		constructor(){}
		work(){
			console.log('work')
		}
		home(){
			console.log('home')
		}
		sleep(){
			console.log('sleep')
		}
		everyday(){
			this.work()
			this.home()
			this.sleep()
		}
	}

	class man extends Human{
		constructor(){super()} //子类必须在constructor方法中调用super方法,否则新建实例时会报错(es6官网写的)
		hasJJ(){console.log('yes,man has jj')}
	}

	class woman extends Human{
		// constructor(){super()} //然后我把这句话删了好像也没事
		hasJJ(){console.log('no,woman no jj')}
	}

	let zhangsan = new man()
	let lisi = new woman()
	zhangsan.hasJJ()
	lisi.hasJJ()
	zhangsan.everyday()
	lisi.everyday()

请问:上述代码中哪一段代码符合模板方法模式?
答:那肯定是继承啊,男人和女人都继承了社畜的上班下班睡觉,然后男的有JJ,女的没JJ是私有方法,俗称男女有别。
然鹅答案是:everyday()才是模板方法模式。
所以我本来只要写human类就可以啦,写什么男人继承人,女人继承人有啥用啊?道理我后面再讲,先明确一个点,模板方法模式指的是我们抽象出一个包含某种大类的事物的一组特定的方法,通常这些方法按顺序执行。
比如我们做菜,一般都是热锅,倒油,放菜,煮菜,放调料,盛菜。所以我们可以把煮菜基本流程封装成一个function cooking(),当我们要做具体的菜的时候,我们就继承一下做菜圣经,然后调用下cooking()方法,当然每道菜煮菜的时间和放的调料不同,这就需要你自己重写了。

误会消除?

在human类例子中,我提到了everyday()才是真正的模板方法,那么为什么“官方”喜欢把模板方法定义为继承才能实现的方法呢?这就涉及到重写了,在炒菜的例子中,我们知道,一般热锅,热油,放菜,盛菜这些步骤都是固定的,但煮菜和放调料就是一门花里胡哨的学问了。因此模板方法里的子方法往往存在重写的可能性,官方的解释里也提到了,父类的模板方法应该是空的,这些模板方法应该由子类重写以实现不同的业务场景。乍一听好像挺有道理的,但我们都知道在JavaScript中函数是可以做参数的,那我直接在子方法里传入一个函数并执行这个函数实现不同的业务场景不就行了嘛,还创建子类继承父类干嘛,直接new一个父类对象不香嘛。所以说JavaScript中完全可以用我说的方法避开什么继承,子类,父类之类这些搞脑子的东西,只要知道模板方法模式是一段执行一组特定函数的代码就行了。

vue中的模板方法模式

通常我们在学习完一个设计模式之后都能想出一些对应的业务场景,显然coffee or tea和human类不符合正常的写代码业务场景,在我能力范围之内,我只能想到一种应用场景——系统架构。系统架构听起来有点过于玄幻,不知道各位有没有使用过vue2.0。当我们在vue搭好的项目中写代码时,会用到methods,data,computed,watch以及生命周期之类的“模板方法”,但需要注意的是,所谓methods,data,computed,watch这些并不是模板方法,Vue实例在初始化的时候执行了一个你不知道的“模板方法”把刚才提到的数据关联成MVVM的模式。因此不要以为methods,data,computed,watch等是模板方法,他们只是模板方法里要用的弟弟们而已。
除此之外,任何有套路的框架都可以称作模板方法模式,比如你在某大佬搭好的框架里写代码,其实就是用了模板方法模式。灵活应用模式,理解模式可以帮助你更好的面试装杯。
加油,打工人!

更多推荐

JavaScript设计模式(8)—— 模板方法模式