Javascript设计原则

在面向对象的程序设计思想中, 我们能够遵循一些原则能够让我们开发代码时结构层次清晰, 更具说服力, 可谓是事半功倍。 做到这一点我们掌握一些程序设计原则是非常有利的, 如果大家研究过数学(或者其他学科)的一些思想方法和解题方法时应该会这个概念有所了解, 设计原则类比数学中的思想方法(如分类讨论, 数形结合等都是思想, 指导你整个学习生涯), 是带有从全局角度的指导性的方案, 设计模式类比与解题方法(如换元法, 数学归纳法等都是针对特定类型的问题的一种解决方案)。 今天介绍一些常见的设计原则, 这些设计原则是独立于语言存在的, 并非Javascript特有。

单一职责原则

理解概念

从名字来看比较好理解, 各自(你创建的函数)干好各自的事情(上级分配的任务, 一般是指你分配)。 在程序世界里, 对象大多数要承担计算任务, 我们暂且把这些任务说成方法, 每个方法各司其职。 如果某个方法承担了过多的职责就会造成职责间的耦合, 致使程序难以维护, 内聚性差。 我们应尽可能的将这些职责分布到更细粒度的方法(或私有方法, 如闭包中的函数)中。 每个方法应该仅有一个引起它变化的原因, 但是这样往往是很困难的, 我们应尽量减少造成方法变化的原因, 一般指方法的参数。 这些方法应该尽可能相互独立, 互不干扰, 避免修改其中一个导致另外的方法产生异常。

使用举例

比如我们需要一个提供创建Ajax的对象。

const Ajax = {
createAjax: function () {
var xhr = null;
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
},
send: function() { }
}; // VS const AjaxBetter = {
ajaxFactory: function ajax() {
if(window.XMLHttpRequest) {
return (this.ajaxFactory = function() {
return new XMLHttpRequest();
})();
} else {
return (this.ajaxFactory = function() {
return new ActiveXObject('Microsoft.XMLHTTP');
})();
}
},
createAjax() {
var xhr = this.ajaxFactory();
return xhr;
},
send: function() { }
};

单一职责原则的优点

粒度细便于代码扩展和复用, 职责独立, 变更单个职责不会影响到其余的职责。

里氏替换原则

理解概念

在子类继承父类时, 子类不能取复写父类的方法。 举例说明一下, 对于父类Car来讲, 它提供了一个move方法, 子类BMW继承自Car时可以拓展Car的move方法但不能对其进行覆盖, move方法能被BMW的子类透明的调用。请看demo:

class Car {
move() {
console.log('I\'m running');
}
}; class BMW extends Car {
run() {
this.move();
console.log('new method');
}
}; const car = new Car();
const bmw = new BMW();
// 父类实例自然能调用move
car.move();
// 子类应能透明调用父类方法, 不要让子类自己也实现一个move方法进而覆盖父类同名方法
bmw.move();
bmw.run();

不覆盖父类的同名方法是防止程序出错, 这和作用域里层同名会遮蔽外层同名变量的目的还不太一样, 我们用子类取继承父类多数是出于代码的复用, 如果取覆盖掉就没有这层意思了, 看下面这个例子:

class Odd {
getOdd(n) {
return 2 * n + 1;
}
}; class Sub extends Odd {
getOdd(n) {
return 2 * n;
} calc(n) {
return this.getOdd(n) * 2;
}
}; const sub = new Sub();
sub.calc(5); // 20, 出错了, 期望是22

这个程序的意图是父类提供一个返回奇数的方法, 子类在继承时无意重写了, 导致子类在calc方法中调用getOdd会得到错误的结果, 以至于程序给出错误的结果

PS: 这里说到的子类不能覆盖父类方法是说不建议这样做, 并不是这样做就会发生语法错误, 子类完全有覆盖父类方法的能力, 如果要违背这一原则请务必三思而后行

依赖倒置原则

理解概念

高层模块不应该依赖底层模块, 二者应依赖其抽象, 抽象不应依赖细节, 细节依赖抽象, 这大多数针对类c语言讲的, 因为js并不具备抽象类概念

const test = {
getValue() {
return 1;
}
}; const other = {
getVal() {
return 10;
}
}; class SimpleMath {
calc(obj) {
console.log(obj.getValue() + 100);
}
}; const s = new SimpleMath();
s.calc(test); // 101
s.calc(other); // 错误

这个错误是显而易见的, other底层类并不具备getValue方法, 所以报错, 我们当然可以修改other让其具备getValue, 可这样难保其他类似的情况, 这里有一个问题, SimpleMath类实例的calc方法与底层对象产生了一个强耦合, 必须具备getValue方法的对象才能传入calc方法, 这就违背了依赖倒置原则的高层模块不依赖底层模块, 所以更好的做法是消除该依赖

const test = {
getValue() {
return 1;
}
}; const other = {
getVal() {
return 10;
}
}; class SimpleMath {
calc(getValue) {
console.log(getValue() + 100);
}
}; const s = new SimpleMath();
s.calc(test.getValue); // 101
s.calc(other.getVal); // 110

Javascript设计原则的更多相关文章

  1. JavaScript设计原则与编程技巧

    1 设计原则概述 <UNIX/LINUX设计哲学>设计准则 ① 小既是美. ② 每个程序只做一件事情. ③ 快速建立原型. ④ 舍弃高效率而取可移植性. ⑤ 避免强制性的图形化界面交互. ...

  2. javascript的api设计原则

    前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来.很难做到 ...

  3. JavaScript 的 API设计原则

    一.接口的流畅性 好的接口是流畅易懂的,他主要体现如下几个方面: 1.简单 操作某个元素的css属性,下面是原生的方法: document.querySelectorAll('#id').style. ...

  4. JavaScript设计模式之设计原则

    何为设计 即按照哪一种思路或者标准来实现功能,功能相同,可以有不同的设计方案来实现 伴随着需求的增加,设计的作用就会体现出来,一般的APP每天都在变化,更新很快,需求不断在增加,如果设计的不好,后面很 ...

  5. REST简介及设计原则

    rest,即REST(Representational State Transfer表述性状态转移)是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性. 简介 REST (R ...

  6. 微观SOA:服务设计原则及其实践方式

    大 量互联网公司都在拥抱SOA和服务化,但业界对SOA的很多讨论都比较偏向高大上.本文试图从稍微不同的角度,以相对接地气的方式来讨论SOA, 集中讨论SOA在微观实践层面中的缘起.本质和具体操作方式, ...

  7. ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则

    ASP.NET MVC 学习笔记-7.自定义配置信息   ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...

  8. 【JS】327- javascript 的 api 设计原则

    点击上方"前端自习课"关注,学习起来~ 前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博 ...

  9. SOLID 设计原则

    SOLID 原则基本概念: 程序设计领域, SOLID (单一功能.开闭原则.里氏替换.接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期 引入的记忆术首字母缩略字,指代了面向对象编程和面向对象 ...

随机推荐

  1. [Flask]celery异步任务队列的使用

    Celery异步任务队列 目录结构树: 配置文件config.py: # 设置中间人地址 broker_url = 'redis://127.0.0.1:6379/1' 主main.py: impor ...

  2. set总结

    set 定义 列表的特性: 可修改 无序 不重复 列表的创建: ​ 1.直接创建; s = {'a', 1, 'c'} ​ 2.set() 创建一个空set; s = set() ​ 3.set(it ...

  3. 51 Nod N^N的末位数字

    1004 n^n的末位数字  题目来源: Author Ignatius.L (Hdu 1061) 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 给 ...

  4. 一些简单题(1)(Source : NOIP历年试题+杂题)

    最近也写了些许题目吧,还是写写博客,捋捋思路. P2216 [HAOI2007]理想的正方形 求一个$a \times b(a,b \leq 10^3)$的矩阵,求出一个$n \times n (n ...

  5. ant design 的表格默认选中

    在使用 ant design 的表格时候使用默认选中项, 需要配置的 Table 的 rowSelection const rowSelection = { type: 'checkbox', get ...

  6. sublime text 3设置

    Sublime text 3 中文文件名显示方框怎么解决? 如图,中文文件名打开全是乱码,内容倒是装了converttoutf8没什么太大的问题. 作者:凝空虚步链接:https://www.zhih ...

  7. MySQ彻底删除与安装配置

    彻底删除 1.查看 MySQL 安装了哪些东西 rpm -qa |grep -i mysql 2.卸载 -.el7.x86_64 -.el7.x86_64 .noarch -.el7.x86_64 - ...

  8. python学习---50行代码实现图片转字符画2

    from PIL import Image codeLib = '''@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<> ...

  9. 如何在外部获取当前A标签的ID值

    <div class="diskmain"> <ul id="folder"> <li><span class='do ...

  10. windows环境安装nexus

    1.下载安装nexus安装包,我用的是nexus-2.14.13-01版本 2. 以管理员身份打开cmd命令窗口 3.进入到nexus bin目录下 输入命令 nexus install 4. 启动 ...