问题不在于"problematic aspect"中的“new”关键字,而在实际方法中更多。
在定义类时,我正在与我的C#和JavaScript思维斗争(ES2015)。在C#中,我使用依赖注入将依赖项注入类的构造函数中。在JavaScript中,由于其原型性质,我了解到没有必要在构造函数中注入依赖项;您可以安全地使用pandas.read_clipboard
,因为稍后您可以稍后模拟该方法以进行单元测试。
因此,许多模块“只是工作”开箱即用,而无需实例化它们。 (节点模块是示例)
我一直在我的项目中使用TypeScript。如您所知,您可以使用Interfaces。我到目前为止所做的是将接口设置为属性,然后将有问题的类设置为它。
为了更好地说明我在说什么,想象一下我有A类:
import
其界面“信”:
class A implements Letter {
hello(){
console.log("Hello World");
}
}
然后我有一个班级“书”,它使用我所说的方法。
interface Letter {
hello(): void
}
它可以像这样使用:
export class Book{
letter : Letter
constructor(){
this.letter = A;
}
Read(){
console.log("We're about to read this chapter!");
this.letter.hello();
}
}
另一方面,我有“BookVersionJs”不使用任何界面并直接实现它:
import {Book} from './book'
let book = new Book();
book.Read();
然后我们可以像这样使用它:
import {A} from './a.ts';
export class BookVersionJs{
Read(){
console.log("We're about to read this chapter!");
A.Hello();
}
}
但我放弃了接口给我的“理论上”松耦合。理论上因为JavaScript可以用原型覆盖它们。
实用性存在差异。我应该在TypeScript / JavaScript中瞄准哪个目标?还是意见问题?
答案 0 :(得分:1)
很难确切地说出你在问什么,但我可以肯定地说我喜欢你的Book
示例的外观远远超过你的BookVersionJs
示例(即使两者都有一些语法错误)有)。
考虑读书。
BookVersionJs
BookVersionJs.Read(); // "I am reading Book"
书
let book = new Book();
book.Read(); // "I am reading a Book"
您的对象应该在语义上有意义,否则任何使用您代码的人都会感到非常困惑。
如果您的关注点是可测试性,那么请务必注入Letter
。您可以将A
保留为默认类型,以便在日常代码中更易于使用,并在单元测试期间提供Letter
的不同实现。
export class Book{
letter : Letter;
constructor(letter: Letter = new A()) { // Note: Assign instance of A, not just A. A is a type, not a value.
this.letter = letter;
}
Read(){
console.log("We're about to read this chapter!");
this.letter.hello();
}
}