浅谈JavaScript 代码整洁之道(9)

不好:

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) => {
  rectangle.setWidth(4);
  rectangle.setHeight(5);
  let area = rectangle.getArea(); // 不好:这里对正方形会返回 25,但应该是 20.
  rectangle.render(area);
 })
}

let rectangles = [new Rectangle(), new Rectangle(), new Square()];
renderLargeRectangles(rectangles);


      

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/417.html