typescript 抽象_为什么要避免TypeScript中的抽象类

typescript 抽象

An abstract class in TypeScript is defined by the abstract keyword. It’s meant to be derived by other classes and not to be instantiated directly.

TypeScript中的抽象类由abstract关键字定义。 它是由其他类派生的,不能直接实例化。

The example below has the BaseLogger, which is an abstract class that enforces derived classes to implement its abstract methods.

下面的示例具有BaseLogger,它是一个抽象类,该类强制派生类实现其abstract方法。

abstract class BaseLogger {
abstract log(msg: string): void
}// Error! Non-abstract class 'DebugLogger' does not implement inherited abstract member 'log' from class 'BaseLogger'.class DebugLogger extends BaseLogger {
// log method must be implemented
}

Abstract classes are similar to interfaces with methods, but one difference is that it can also contain shared implementations. Note that these do not have the abstract keyword in front of the method names.

抽象类类似于带有方法的接口,但是区别在于它也可以包含共享的实现。 请注意,这些方法名称前面没有abstract关键字。

abstract class BaseLogger {
abstract log(msg: string): void public formatMessage(msg: string): string {
return msg.toLowerCase();
}
}class DebugLogger extends BaseLogger {

public log(msg: string): void {
const formattedMessage = this.formatMessage(msg); console.log(msg);
}
}

In theory, this works nicely as a way to share code. In practice however, I found the benefits of code sharing are often overestimated, especially as the number of implementations on the abstract class grow over time. Then it starts to take more time to understand the abstraction than to just have the duplication. When there is truly shareable code, prefer composition over inheritance. For this reason, I try to avoid abstract classes and prefer utilities and interfaces, which follow the single-responsibility principle more closely.

从理论上讲,这很好地用作共享代码的一种方式。 但是在实践中,我发现代码共享的好处经常被高估,尤其是随着抽象类的实现数量随着时间的增长而增加。 然后,开始花更多的时间来理解抽象,而不是仅仅进行复制。 当存在真正可共享的代码时,最好使用组合而不是继承 。 因此,我尝试避免抽象类,而更喜欢实用程序和接口,它们更紧密地遵循单一职责原则。

// Use interfaces to enforce implementationexport interface Logger {
log(msg: string): void;
}// Use utilities to share codeexport const formatMessage = (msg: string) => msg.toLowerCase()// in DebugLogger.ts
class DebugLogger implements Logger {

public log(msg): void {
const formattedMessage = formatMessage(msg); console.log(msg);
}
}

While the code above achieves the same goal, the extracted utility has an added benefit of testability. Remember, you can’t instantiate abstract classes and therefore they are not testable independently. While you can argue that abstract classes as an implementation detail of the extending class, it still means less amount of code covered by unit tests, which are cheaper than integration tests.

尽管上面的代码实现了相同的目标,但提取的实用程序具有可测试性的其他优点。 请记住,您不能实例化抽象类,因此它们不能独立测试。 尽管您可以说抽象类是扩展类的实现细节,但它仍然意味着单元测试所覆盖的代码量更少,这比集成测试便宜。

// Error! Cannot create an instance of an abstract class.
const baseLogger = new BaseLogger();

Finally, it also takes longer to track down implementations, even with VSCode IntelliSense. One benefit of using classes over interfaces is that your definition and implementation live in one place, a quick keypress when using the ‘Go to Definition’ functionality. In contrast, if you try to debug an abstract class method that rely on implementation from derived classes, it will often have you search through multiple implementations, hopping between files.

最后,即使使用VSCode IntelliSense ,也需要花费更长的时间来跟踪实现 。 通过接口使用类的一个好处是,您的定义和实现可以放在一个地方,使用“转到定义”功能时,只需按一下快捷键即可。 相反,如果您尝试调试依赖于派生类中的实现的抽象类方法,则通常会使您搜索多个实现,并在文件之间跳转。

abstract class BaseLogger {
abstract log(msg: string): void public logWithInfo(msg: string): string {
// Where is the implementation of this.log?
return this.log(`${msg} + 'some extra info');
}
}

In summary, readability, testability, and developer ergonomics are all reasons why I try to avoid abstract classes when possible.

总而言之,可读性,可测试性和开发人员的人机工程学都是我尽可能避免抽象类的原因。

翻译自: https://medium.com/javascript-in-plain-english/why-you-should-avoid-abstract-classes-in-typescript-bcbdd3a87db6

typescript 抽象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值