Javascript设计原则
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设计原则的更多相关文章
- JavaScript设计原则与编程技巧
1 设计原则概述 <UNIX/LINUX设计哲学>设计准则 ① 小既是美. ② 每个程序只做一件事情. ③ 快速建立原型. ④ 舍弃高效率而取可移植性. ⑤ 避免强制性的图形化界面交互. ...
- javascript的api设计原则
前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博文同时也参考了其他一些文章,相关地址会在后面贴出来.很难做到 ...
- JavaScript 的 API设计原则
一.接口的流畅性 好的接口是流畅易懂的,他主要体现如下几个方面: 1.简单 操作某个元素的css属性,下面是原生的方法: document.querySelectorAll('#id').style. ...
- JavaScript设计模式之设计原则
何为设计 即按照哪一种思路或者标准来实现功能,功能相同,可以有不同的设计方案来实现 伴随着需求的增加,设计的作用就会体现出来,一般的APP每天都在变化,更新很快,需求不断在增加,如果设计的不好,后面很 ...
- REST简介及设计原则
rest,即REST(Representational State Transfer表述性状态转移)是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性. 简介 REST (R ...
- 微观SOA:服务设计原则及其实践方式
大 量互联网公司都在拥抱SOA和服务化,但业界对SOA的很多讨论都比较偏向高大上.本文试图从稍微不同的角度,以相对接地气的方式来讨论SOA, 集中讨论SOA在微观实践层面中的缘起.本质和具体操作方式, ...
- 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 ...
- 【JS】327- javascript 的 api 设计原则
点击上方"前端自习课"关注,学习起来~ 前言 本篇博文来自一次公司内部的前端分享,从多个方面讨论了在设计接口时遵循的原则,总共包含了七个大块.系卤煮自己总结的一些经验和教训.本篇博 ...
- SOLID 设计原则
SOLID 原则基本概念: 程序设计领域, SOLID (单一功能.开闭原则.里氏替换.接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期 引入的记忆术首字母缩略字,指代了面向对象编程和面向对象 ...
随机推荐
- 修改 Linux 服务器时间
1.当前时间 [app@127-0-0-1 shine]$ date Wed Oct 23 11:44:30 CST 2019 2.修改时间 [app@127-0-0-1 shine]$ date - ...
- head first 设计模式笔记6-命令模式
命令模式:将“请求”封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作.这个模式允许我们将动作封装成命令对象,然后可以传递和调用. 1)命令模式将发出请求的对象和 ...
- jquery result属性 语法
jquery result属性 语法 作用:result 属性包含由被指定事件触发的事件处理器返回的最后一个值,除非这个值未定义.大理石平台精度等级 语法:event.resul 参数: 参数 描述 ...
- 手动升级 Confluence 6 - 升级问题解决
升级失败了? 如果你需要对你的升级进行回退,你必须首先恢复你老的 Confluence 备份.不要尝试再次进行升级,也不要尝试再次对升级失败的 Confluence 进行再次启动. 在升级过程中遇到 ...
- RedHat6.2系统安装ipvsadm+keepalived
一.安装IPVS 软件包下载: 链接:https://pan.baidu.com/s/1zNgPtALbdBTC1H6e0IaZPw 提取码:xm7t 1.检查内核模块,看一下ip_vs 是否被加载 ...
- php的 strval函数
官方的解释 PHP strval() 函数 PHP 可用的函数 strval() 函数用于获取变量的字符串值. PHP 版本要求: PHP 4, PHP 5, PHP 7 语法 string strv ...
- python环境下安装virtualenv,virtualenvwrapper
在使用 Python 开发的过程中,工程一多,难免会碰到不同的工程依赖不同版本的库的问题: 亦或者是在开发过程中不想让物理环境里充斥各种各样的库,引发未来的依赖灾难. 此时,我们需要对于不同的工程使用 ...
- Linux系统下MySql表名大小写敏感问题
mysql是通过lower_case_table_names变量来处理大小写问题的. 首先查询该变量 mysql在Linux下数据库名.表名.列名.表别名大小写规则如下: 1.数据库名与表名严格区分大 ...
- 微信小程序需求IIS服务器配置https关于SSL,TLS的综合解决方案
SpringBoot配置SSL同时支持http和https访问 传输层安全性协议(英语:Transport Layer Security,缩写作 TLS),及其前身安全套接层(Secure Socke ...
- Java多线程深度探索
线程 1.优先级 每个线程有一个优先级,更高优先级的线程优先运行,优先的意思是只是在分配cpu时间段的时候,得到的概率高一些.当在某个线程创建一个新的线程,这个线程有与创建线程相同的优先级.setPr ...