首页 存档 技术 查看内容

JavaScript 代码整洁之道(中)

2018-3-30 13:00 |来自: 互联网 332 0

摘要: 目录 概述 变量 函数 对象和数据结构 类 测试 并发 错误处理 格式 注释 类 单一职责原则 (SRP) 正如《代码整洁之道》所说,“不应该有超过一个原因来改变类”。往一个类里塞进许多功能是件诱人的事情,就像在坐飞 ...

目录

  1. 概述

  2. 变量

  3. 函数

  4. 对象和数据结构

  5. 测试

  6. 并发

  7. 错误处理

  8. 格式

  9. 注释

单一职责原则 (SRP)

正如《代码整洁之道》所说,“不应该有超过一个原因来改变类”。往一个类里塞进许多功能是件诱人的事情,就像在坐飞机的时候只带一个手提箱一样。这带来的问题是,你的类不会在概念上有凝聚力,会有很多因素造成对它的改变。让你的类需要改变的次数最少是件非常重要的事情。这是因为如果一个类里塞入了太多功能,你只修改它的一部分,可能会让人难以理解它为何会影响代码库中其它相关模块。

不好:

class UserSettings {
 constructor(user) {
  this.user = user;
 }

 changeSettings(settings) {
  if (this.verifyCredentials(user)) {
   // ...
  }
 }

 verifyCredentials(user) {
  // ...
 }
}

:

class UserAuth {
 constructor(user) {
  this.user = user;
 }

 verifyCredentials() {
  // ...
 }}class UserSettings {
 constructor(user) {
  this.user = user;
  this.auth = new UserAuth(user)
 }

 changeSettings(settings) {
  if (this.auth.verifyCredentials()) {
   // ...
  }
 }
}

开放封装原则(OCP)

正如 Bertrand Meyer 所说,“软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。”这是什么意思呢?这个原则基本上规定了你应该允许用户扩展你的模块,但不需要打开.js源代码文件来进行编辑。

不好:

class AjaxRequester {
 constructor() {
  // 如果我们需要另一个 HTTP 方法,比如 DELETE,该怎么办?
  // 我们必须打开这个文件然后手工把它加进去
  this.HTTP_METHODS = ['POST', 'PUT', 'GET'];
 }

 get(url) {
  // ...
 }
}

:

class AjaxRequester {
 constructor() {
  this.HTTP_METHODS = ['POST', 'PUT', 'GET'];
 }

 get(url) {
  // ...
 }

 addHTTPMethod(method) {
  this.HTTP_METHODS.push(method);
 }
}

里氏替换原则(LSP)

这是一个吓人的术语,但描述的却是个简单的概念。它的正式定义为“如果 S 是 T 的子类,那所有 T 类型的对象都可以替换为 S 类型的对象(即 S 类型的对象可以替代 T 类型的对象),这个替换不会改变程序的任何性质(正确性、任务执行等)。”这确实是个吓人的定义。

对此最好的解释是,如果你有父类和子类,那么父类和子类可以交替使用而不会造成不正确的结果。这可能仍然让人感到疑惑,那么让我们看看经典的正方形和矩形的例子。在数学上,正方形也是矩形,但是如果你在模型中通过继承使用 “is-a” 关系,你很快就会陷入困境。

不好:

class Rectangle {
 constructor() {
  this.width = 0;
  this.height = 0;
 }

 setColor(color) {
  // ...
 }

 render(area) {
  // ...
 }

 setWidth(width) {
  this.width = width;
 }

 setHeight(height) {
  this.height = height;
 }

 getArea() {
  return this.width * this.height;
 }
}

class Square extends Rectangle { constructor() { super(); } setWidth(width) { this.width = width; this.height = width; } setHeight(height) { this.width = height; this.height = height; }
}

function renderLargeRectangles(rectangles) { rectangles.forEach((rectangle) =
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部