使用ES6类时,为什么不通过构造函数传递依赖项,而不是将它们作为导入/要求列在顶部:例如
class DEF {
constructor(ABC) {
this.abc = new ABC();
}
}
代替
const ABC = require('./abc');
class DEF {
constructor() {
this.abc = new ABC();
}
}
我想了解这些编程风格之间的区别以及两者的含义?
答案 0 :(得分:2)
这是Dependency Injection的一种形式,在各种情况下都可能有用。例如进行测试。
通常您会做类似的事情
@objc func sliderValueDidChange(sender:UISlider) {
dayFeelings01.frame.size.width = CGFloat(sender.value)
}
,然后在测试文件中提供自定义const DefaultABC = require('./abc');
class DEF {
constructor(ABC = DefaultABC) {
this.abc = new ABC();
}
}
实现。这可能比模拟模块或劫持模块的解析和加载要简单。
答案 1 :(得分:0)
因为有时需要通过不同的课程:
new Vehicle(/*for*/ Animal)
new Vehicle(/*for*/ Human)
答案 2 :(得分:0)
在第一个示例中,您可以使用不同版本的ABC,只要它们实现相同的接口即可。这提供了比后者宽松的耦合,但缺点是您需要充分了解DEF将如何在内部使用ABC来确保接口匹配。
在第二个示例中,您不必担心使用哪个版本的ABC。现在,这两个类彼此紧密结合,其优点是只需要知道DEF的工作原理,而无需了解ABC。
因此,这两种“样式”都会解决不同的问题。
当我希望能够将不同的可选组件“插入” DEF时,我将使用第一种样式。 但是在扩展类时,我将使用第二种样式。
答案 3 :(得分:0)
这非常取决于用例。问题是决策在哪里?
如果您的工作是决定使用哪种原型方法来实例化新对象?还是您希望调用者决定使用哪种原型方法?在设计应用程序时应提出并思考这些问题,并应根据设计分歧来分配职责。
以一个简单的加法为例:
hello everyone
Segmentation fault
在上述情况下,决策取决于内部。我无法提供要返回的对象类型。我唯一的责任是提供正确的对象。您可以将其与虚构的变体进行权衡:
1 + 1 //=> 2
1 + '1' //=> '11'
两者都不对。