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. 使用oracle Sqlplus中上下键出现乱码的问题

    安装rlwrap,前提是安装readline和readline-devel yum list | grep readlineyum install -y readline.x86_64 readlin ...

  2. layui 批量上传

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="piclist.aspx.c ...

  3. HTML+CSS之光标悬停图片翻转效果

    设计思路:         首先做一个包括图片和说明文字的简单的页面结构,然后再设置它的变换.将变换的元素,即照片和文字放在一个父容器里面,这就需要四个父容器 ,再将这四个父容器放在最外层的舞台上面进 ...

  4. 1209F - Koala and Notebook

    这场比赛没打,看同学fst了,于是来看看. 这道题看似简单,但是没想清楚细节真的不太行.像现在熬到十一点左右,脑子真的不行. 首先显然位数越小越好,因为每一位要比较,不如拆点.此时要拆成两条有向链(开 ...

  5. Unity3D_(游戏)2D简单游戏制作过程:捕获高空掉落保龄球

      游戏介绍:通过鼠标的左右移动,可以控制帽子的移动,当帽子接到下落的保龄球时,会出现火花效果.没有接到保龄球时,保龄球落到草地上,过10S后会自动消失. 实现效果: 素材+Unity3D源代码:传送 ...

  6. XCTF简单的php

    看看源码 <?php show_source(__FILE__); include("config.php"); $a=@$_GET['a']; $b=@$_GET['b'] ...

  7. idea 下运行安卓项目

    修改 gralde 路径修改安卓sdk路径进入project structure 设置 Project settings / Project /project SDK 选择 Android API 2 ...

  8. Hibernate持久化类规则

    注意事项: 提供无参的构造方法,因为在hibernate需要使用反射生成类的实例 提供私有属性,并对这些属性提供公共的setting和getting方法,因为在hibernate底层会将查询到的数据进 ...

  9. Spring之AOP配置

    特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...

  10. axios的数据请求方式及跨域

    express 的三大功能:静态资源.路由.模板引擎 app.use(express.static('www')); 只要是创建这个静态的目录,这个 www 的静态目录里面的文件就可以被访问 数据的请 ...