javascript - SOLID - 依赖倒置原则:实用程序/辅助函数应该是一个接口还是我可以使用它的具体实现?
问题描述
给定这个伪代码,它有一个带有冗长代码的 if 语句(想象这是一个非常冗长的 if 语句),我决定创建一个 util 函数来使我的代码更简洁。当我选择创建一个 util 函数时,它应该作为接口实现还是可以实现具体函数?我可能会在其他课程中再次使用相同的功能。
虚拟代码:
export class UserRepository {
constructor (private readonly database: DatabaseProtocol) {}
async findUserByEmail (data: Record<string, any>): Promise<IUser | null> {
const userCollection = this.database.collection('users')
if (Object.keys(data).length === 0) return null
const user = await userCollection.findOne({ email: data.email })
return user
}
}
具体实施:
export class UserRepository {
constructor (private readonly database: DatabaseProtocol) {}
async findUserByEmail (data: Record<string, any>): Promise<IUser | null> {
const userCollection = this.database.collection('users')
if (isEmpty(data)) return null
const user = await userCollection.findOne({ email: data.email })
return user
}
}
接口实现:
export class UserRepository {
constructor (
private readonly database: DatabaseProtocol,
private readonly isEmpty: IsEmptyProtocol
) {}
async findUserByEmail (data: Record<string, any>): Promise<IUser | null> {
const userCollection = this.database.collection('users')
if (this.isEmpty(data)) return null
const user = await userCollection.findOne({ email: data.email })
return user
}
}
私有方法:
export class UserRepository {
constructor (
private readonly database: DatabaseProtocol
) {}
async findUserByEmail (data: Record<string, any>): Promise<IUser | null> {
const userCollection = this.database.collection('users')
if (this.isEmpty(data)) return null
const user = await userCollection.findOne({ email: data.email })
return user
}
isEmpty (data: Record<string, any>): boolean {
return Object.keys(data).length === 0
}
}
以上哪个选项被认为是最佳实践?
解决方案
这是我的 2 美分:
- 如果
IsEmpty
仅UserRepository
类需要该功能,则将其设为该类的私有方法。 - 如果
IsEmpty
您的程序中的某些(并非全部)分类需要该功能,那么请使用Interface implementation:
您在问题中提出的解决方案。 - 如果
IsEmpty
您的所有类(或绝大多数类)中都使用了该功能,则将其设为具有静态方法的全局类。我知道,我知道,鲍勃叔叔不允许全局状态(这是理所当然的),但这是一个例外。这个案例是一个跨领域的问题(请从更多细节中查看我的答案)。
推荐阅读
- ocmock - iOS Obj-C unittest 应用程序不会以添加 OCMock 和 XCTest 开始
- mysql - 等于操作不适用于具有更新排序规则的字段
- entity-framework-core - 如何映射 EFCore DBFirst 外键拆分主键
- c++ - 什么是 STL 队列的 C++ 迭代器?
- c# - 更改字符串中的特殊字符
- javascript - ReactJS 状态值在输入 onChange 时未正确更新
- docker - 如何在 Windows 终端中打开 root@ad02e79cfb5b 目录?
- javascript - 如何将我的反应应用程序中的对象添加到 Firebase Firestore?错误:无效数据。不支持的字段值:自定义的 timingVector 对象
- objective-c - NSLider 的 setHidden 不起作用 - 目标 C
- javascript - 如何自定义 React Native Navigation Cardoverlay 样式?