前提已经提到,JavaScript 没有接口,因此抽象依赖于隐性契约。也就是说,一个对象/类会把方法和属性暴露给另一个对象/类。在下面的例子中,隐性契约是任何用于 InventoryTracker 的 Request 模块都应该拥有 requestItems 方法。
不好:
class InventoryTracker {
constructor(items) {
this.items = items;
// 不好:我们创建了一个依赖于特定请求的实现。
// 我们应该只依赖请求方法:`request` 的 requestItems
this.requester = new InventoryRequester();
}
requestItems() {
this.items.forEach((item) => {
this.requester.requestItem(item);
});
}
}
class InventoryRequester {
constructor() {
this.REQ_METHODS = ['HTTP'];
}
requestItem(item) {
// ...
}
}
let inventoryTracker = new InventoryTracker(['apples', 'bananas']);
inventoryTracker.requestItems();
好:
class InventoryTracker {
constructor(items, requester) {
this.items = items;
this.requester = requester;
}
requestItems() {
this.items.forEach((item) => {
this.requester.requestItem(item);
});
}
}
class InventoryRequesterV1 {
constructor() {
this.REQ_METHODS = ['HTTP'];
}
requestItem(item) {
// ...
}
}
class InventoryRequesterV2 {
constructor() {
this.REQ_METHODS = ['WS'];
}
requestItem(item) {
// ...
}
}
// 通过构建外部依赖并注入它们,我们很容易把请求模块替换成
// 一个使用 WebSocket 的新模块。
let inventoryTracker = new InventoryTracker(['apples', 'bananas'], new InventoryRequesterV2());
inventoryTracker.requestItems();
多用 ES6 类语法,少用 ES5 构造函数语法
在经典的 ES5 的类定义中,很难找到易读的继承、构造、方法定义等。如果你需要继承(你会发现做不到),那就应该使用类语法。不过,应该尽可能使用小函数而不是类,直到你需要更大更复杂的对象。
不好:
var Animal = function(age) {
if (!(this instanceof Animal)) {
throw new Error("Instantiate Animal with `new`");
}
this.age = age;
};
Animal.prototype.move = function() {};
var Mammal = function(age, furColor) {
if (!(this instanceof Mammal)) {
throw new Error("Instantiate Mammal with `new`");
}
Animal.call(this, age);
this.furColor = furColor;
};
Mammal.prototype = Object.create(Animal.prototype);
Mammal.prototype.constructor = Mammal;
Mammal.prototype.liveBirth = function() {};
var Human = function(age, furColor, languageSpoken) {
if (!(this instanceof Human)) {
throw new Error("Instantiate Human with `new`");
}
Mammal.call(this, age, furColor);
this.languageSpoken = languageSpoken;
};
Human.prototype = Object.create(Mammal.prototype);
Human.prototype.constructor = Human;
Human.prototype.speak = function() {};
好:
class Animal {
constructor(age) {
this.age = age;
}
move() {}
}
class Mammal extends Animal {
constructor(age, furColor) {
super(age);
this.furColor = furColor;
}
liveBirth() {}
}
class Human extends Mammal {
constructor(age, furColor, languageSpoken) {
super(age, furColor);
this.languageSpoken = languageSpoken;
}
speak() {}
}
内容版权声明:除非注明,否则皆为本站原创文章。
