首页 > 解决方案 > 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
  }
}

以上哪个选项被认为是最佳实践?

标签: javascriptnode.jstypescriptoopsolid-principles

解决方案


这是我的 2 美分:

  1. 如果IsEmptyUserRepository类需要该功能,则将其设为该类的私有方法。
  2. 如果IsEmpty您的程序中的某些(并非全部)分类需要该功能,那么请使用Interface implementation:您在问题中提出的解决方案。
  3. 如果IsEmpty您的所有类(或绝大多数类)中都使用了该功能,则将其设为具有静态方法的全局类。我知道,我知道,鲍勃叔叔不允许全局状态(这是理所当然的),但这是一个例外。这个案例是一个跨领域的问题(请从更多细节中查看我的答案

推荐阅读