JavaScript-在不修改程序源代码增加新功能(开放-封闭原则)

在我们工作中经常会遇到一些“祖传代码“要我们接手,在还没熟悉的时候突然有了新的需求,比如在一个testLoad函数中打印出所有节点的数量。这个难不倒我们,打开编辑器,搜索出 testLoad函数在的文件中的位置,在函数内部添加以下代码:

testLoad = function () {  // 此处省略代码  console.log('源函数的操作内容');  // 新增操作代码  console.log('输出所有节点数量', document.getElementsByTagName('*').length);}

这时候在我们对祖传代码完全不了解的情况下,尤其是一些比较大的函数时候,我们不太想直接在函数中修改,牵一发而动全身的操作,让我们经常无意间触发新的bug。甚至,有时候不经意间还会触发一系列的连锁反应。
那么,有没有办法在不修改代码的情况下,就能满足新需求呢?通过增加代码,而不是修改代码的方式,来给testLoad函数添加新的功能,代码如下:

Function.prototype.after = function (afterfn) {  let _this = this;  return function () {    let ret = _this.apply(this, arguments);    afterfn.apply(this, arguments);    return ret;  }}testLoad = (testLoad || function () { }).after(function () {  console.log(document.getElementsByTagName('*').length);})

通过动态装饰的方式,我们完全不用理会从前window.onload 函数的内部实现,无论它的实现优雅或是丑陋。就算我们作为维护者,拿到的是一份混淆压缩过的代码也没有关系。只要他从前是个稳定运行的函数,那么以后也不会因为我们的新增需求而产生错误。新增的代码和原有的代码可以井水不犯河水。
通过对testLoad函数扩展功能时,用到了两种方式。一种是修改原有的代码,另一种增加一段新的代码。使用哪种方式效果更好,已经不言而喻。
现在可以引出开放-封闭原则的思想:当需要改变一个程序的功能或者给这个程序增加新功能的时候,可以使用增加代码的方式,但是不允许改动程序的源代码。
开放-封闭原则最早由Eiffel语言的设计者Bertrand Meyer在其著作Object-Oriented Software Construction中提出。它的定义如下:

软件实体(类、模块、函数)等应该是可以扩展的,但是不可修改。

本篇就到这里,一个简单的开放-封闭原则,下方给出完整代码:

let testLoad = function () {  // 此处省略代码  console.log('源函数的操作内容');  // 新增操作代码  console.log('输出所有节点数量', document.getElementsByTagName('*').length);}Function.prototype.after = function (afterfn) {  let _this = this;  return function () {    let ret = _this.apply(this, arguments);    afterfn.apply(this, arguments);    return ret;  }}testLoad = (testLoad || function () { }).after(function () {  console.log(document.getElementsByTagName('*').length);})

本文内容主要来自《JavaScript设计模式与开发实践》-曾探

来源:https://www.icode9.com/content-1-847301.html

(0)

相关推荐