scala - 构造函数参数与抽象成员(类与抽象类)
问题描述
什么时候应该使用抽象类而不是常规类?更具体地说,我试图了解何时应该优先使用构造函数参数而不是抽象成员。
例如:
sealed trait Client
abstract class BaseService {
def client: Client
}
class Service extends BaseService {
val client = ???
}
对比
sealed trait Client
class BaseService(client: Client) {}
class Service extends BaseService(client = ???)
据我所知,两者都是有效的。
解决方案
正如@Luis Miguel 所说,当您想要声明一组需要由子类实现的通用方法和/或共享将由所有子类使用的一些有限功能时,请使用抽象类。
下面,我列出了一些我认为应该将依赖项传递给构造函数而不是在类/基类中定义它们的原因。
使用依赖注入
(恕我直言)最好为构造函数提供正常运行所需的依赖项 AKA依赖注入。
避免紧耦合
当您在类或构造函数中声明依赖项时,您将与依赖项的特定实现紧密耦合Service
,这并不理想,被认为是反模式。
编程接口,而不是实现
注入依赖项为您提供了更大的灵活性,因为您不耦合到特定的实现。只要您的代码依赖于接口/特征/抽象类(因此避免紧密耦合),这是正确的。
当您的类依赖于接口/特征/抽象类时可能非常强大,因为您可以传递模拟、无操作或客户端的不同策略。因此,请确保您“编程到接口,而不是实现”。
推荐阅读
- python - 尝试运行 jupyter notebook 时模块“attr”中的错误
- arrays - VBA - 将长整数放入字节数组?
- c# - 不要破坏加载对象和游戏数据
- vuejs2 - 如何解决:“不能在异步函数之外使用关键字‘await’”
- python - 在维护行的同时连接列
- arrays - “按值传递的参数”CLRS 算法
- ios - ld:未找到架构 x86_64 Xcode 10.3 的符号
- c# - 尝试在 main 方法中调用类构造函数,以便创建报告卡
- javascript - 如果 URL 不包含哈希(未指定输入文件),Vue 路由会中断
- java - 我需要从这个 2D String 方法返回什么?