1

看过一些关于Scala的蛋糕模式的文章,基本明白了。以下是我从本文中复制的一些示例代码:

成分:

case class User(username:String, password: String)

trait UserRepositoryComponent {
  val userRepository: UserRepository

  class UserRepository {
    def authenticate(user: User): User = { 
      println("authenticating user: " + user)
      user
     }
    def create(user: User) = println("creating user: " + user)
    def delete(user: User) = println("deleting user: " + user)
  }
}


trait UserServiceComponent { this: UserRepositoryComponent =>
  val userService: UserService
  class UserService {
    def authenticate(username: String, password: String): User = 
      userRepository.authenticate(User(username, password))  

    def create(username: String, password: String) = 
      userRepository.create(new User(username, password))

    def delete(user: User) = 
      userRepository.delete(user)

  }
}

组合它们的对象:

object ComponentRegistry extends 
  UserServiceComponent with 
  UserRepositoryComponent {
  val userRepository = new UserRepository
  val userService = new UserService
}

object TestingComponentRegistry extends 
  UserServiceComponent with 
  UserRepositoryComponent {
  val userRepository = mock[UserRepository]
  val userService = mock[UserService]
}

如果我在一个简单的项目中,我想让它更简单。代码将如下所示:

case class User(username:String, password: String)

class UserRepository {
  def authenticate(user: User): User = { 
    println("authenticating user: " + user)
    user
   }
  def create(user: User) = println("creating user: " + user)
  def delete(user: User) = println("deleting user: " + user)
}

class UserService(userRepository: UserRepository) {
  def authenticate(username: String, password: String): User = 
    userRepository.authenticate(User(username, password))  

  def create(username: String, password: String) = 
    userRepository.create(new User(username, password))

  def delete(user: User) = 
    userRepository.delete(user)

}

将它们组合起来:

object Application {
  val userService = new UserService(new UserRepository)
}

object Test {
  val userService = new UserService(mock[UserRepository]) 
}

我的问题是,我的代码仍然可以被视为“依赖注入”吗?

  1. UserService我在的构造函数中声明了依赖项
  2. 我将它们与不同环境中的对象结合起来

但我没有提供一些特征作为“组件”。

4

1 回答 1

3

是的,您的代码是“依赖注入”:UserService接收它应该用作构造函数参数的组件,而不是UserRepository直接在内部实例化UserService

恕我直言,您的代码正是DI 应该是 90+% 的时间。不需要像 Spring 或 Guice 这样的“花哨”框架,不需要像蛋糕模式这样的“花哨”设计模式,只需在构造函数中注入你的依赖项即可。完成,干净,易于测试,易于换出不同的实现(*)。

(*):请注意,在您的示例中实现这一点UserRepository可能应该是一个特征而不是一个类。

于 2014-06-19T14:55:21.367 回答