前言
上一期我们,浅尝辄止,稍微介绍了下代码如何写才能更高级,更有内涵,主要是需要配合继承,或是某些数据特性来说。这一节咱们放个大招,运用兵法来写代码,保证初学者看不懂,既便能看懂,也不知道为什么这样做,即便知道为什么这样做,没有系统学习过的人也做不好,也说不出个所以然来。
这部兵法就是– 设计模式 。
何为设计模式?
古有云:“何谓虽练无益?今一营之卒为炮手者常十也。不知兵法五兵迭用,当长以卫短,短以救长,一也。”
(翻译成人话)
意思就是训练要有意义,不能瞎练。类比到我们写代码,就是要按照一定的章法,什么时候改写什么,怎么写,要符合核心思想,这样写出来的代码,美观,漂亮,可维护性强,不易出错,而且关键的是,别人看不懂。
那么核心思想是什么,就是 根据你的目的去筛选要使用的设计模式 ,比如说现在有一个需求,让你给一个天气预报的功能块下方增加一个 PM 指数的展示,当然你可以直接在天气预报的方法最下面增加一个展示 PM 值的小方法。
不过这样就污染了原先的函数,导致函数功能不单一,第一不好维护,第二,复用不方便。当有别处需要使用天气功能,但是不想添加 PM 值的时候,该函数又得修改,判断是何处调用的,来确定要不要执行 PM 方法。
那么该怎么解决这个问题,才是符合兵法的呢?
我们可以给 Function 函数的原型上设置一个 after 方法,让这个方法在执行完函数后触发,这样把显示 PM 的方法放到 after 里面,不会对原函数造成污染,而且需要的时候,加上 after 函数,不需要的时候,我们就不使用 after ,也保证了原函数的复用性。
具体做法如下:
//在执行函数 前 执行
Function.prototype.before = function (beforefn) {
let _self = this; //保存原函数引用
return function () { //返回包含了原函数和新函数的"代理函数"
beforefn.apply(this, arguments); //执行新函数,修正this
return _self.apply(this, arguments); //执行原函数
}
};
//在执行函数 后 执行
Function.prototype.after = function (afterfn) {
let _self = this;
return function () {
var ret = _self.apply(this, arguments);
afterfn.apply(this, arguments);
return ret;
}
};
上面在Function的原型上,增加了两个方法,一个 before ,一个 after , before 会在函数执行前先执行, after 会在函数执行后立即执行。
使用的时候只需要指定对应的函数即可,如下:
let func = function () {
console.log('天气预报');
}
func = func.before(function () {
console.log('天气预报之前执行的函数');
}).after(function () {
console.log('之后执行的PM方法');
});
func();//天气预报之前执行的函数
//天气预报
//之后执行的PM方法
这回如果后面需要升级增加新功能,也都可以放在我们设置的这两个函数里,是不是感觉后面的路越来越轻松了。讲到这里,似乎有些跑题。这个方法和兵法有什么关系?
别着急,上面这种,不破坏原函数,只是通过某种方法,对原函数进行功能增加的手段,就是设计模式中的 装饰者模式 ,是不是不知不觉的我们就融入灵魂了。
装饰者模式
这个也叫装饰器模式,是一种比较常见的设计模式,举个例子,比如穿衣服,不同的衣服款式不同,颜色不同,所适合的场合也不同,无论增加什么样子的衣服,人还是不变的,他的高矮胖瘦不会随衣服变化,换句话说,衣服只是我们为了达到某种目的(比如为了吸引异性)的一种手段,这个手段只到起装饰作用,并不起到决定性作用。
有一点需要注意,穿衣服,脱衣服的过程是简单易实现的,这一点很重要,如果不能很方便的穿脱服装,每次恨不得扒一层皮下来,那这个过程就失去了意义。(做衣服的过程可以稍微复杂,因为衣服只需要做一次,做好之后我们随用随穿)
适用环境
这种思想比较适合在已经成型的项目上增加新的功能,项目中的各个函数,方法一般都要求高内聚,低耦合。模块之间各干各的,别掺和其他人的事。
总结
通过上面的几部分的描述,简单总结一下,设计模式是前辈们在长期编码过程中总结出来的一套编码习惯,这些习惯可以让我们在编码过程中提高效率。(这里的效率不仅指编码过程中,同时还能提高项目的效率,使整体代码可维护,易修改,方便阅读和使用)。
补充一点,设计模式是不受语言的限制的,语言的不同只是实现方式的不同,而思想永远是一致的。所以古人常说,兵法精髓,在于一个“ 奇 ”字。
今后的文章,我会对各个设计模式进行逐一的介绍,我个人也在边学习边总结,文中有出错的地方,各位前辈多多指点。