【问题标题】:DAO in Scala with type classes带有类型类的 Scala 中的 DAO
【发布时间】:2011-04-12 14:37:41
【问题描述】:

让我的应用程序包含业务类OrderProductCustomer 等,我想在数据库中/从数据库中存储/检索它们。

通常,我们为此使用DAO 模式。也就是说,我们为每个业务类定义了一个DAO 接口和实现:OrderDAOProductDAO 等。现在我想使用 type class 模式:

trait DAO[T] {
  def create(t:T)
  ... // other CRUD operations
}
...
// DAO implementations for specific business objects
implicit object OrderDAO extends DAO[Order] {
   def create(o:Order) {...}
   ... // other CRUD operations
}
...
// create a business object in the database
def create[T](t:T)(implicit dao:DAO[T]) {dao.create(t)}

现在我的问题是所有DAOs 都使用DataSource 实例(数据库连接工厂),因此我无法将DAOs 定义为objects。我应该创建一个 DataSource 的单例实例,并在初始化时将其传递给所有 DAOs

假设我们有一个创建DataSource的函数:

def dataSource():DataSource = {...}
您将如何使用 type classes 实现 DAOs

【问题讨论】:

    标签: scala dao implicit


    【解决方案1】:

    我不认为类型类是去这里的方式。类型类用于描述能力,而不是作为 DI 的替代品。

    例如,如果您的 DAO 写入键值存储,它可能需要将类转换为键和值的 Map 的能力。

    在这种情况下,类型类是:

    trait KeyValuable[T] {
      def toMap(t: T): Map[String, String]
    }
    

    很明显,无论环境如何,您都可以为每个业务类提供正确的实现。它是类型的继承能力,与您如何使用它无关。

    【讨论】:

      【解决方案2】:

      如何创建一个包含所有 DAO 并使用 DataSource 初始化它们的对象?额外的间接,但这会起作用。

      我不知道(尚)在 Scala 中处理依赖注入的最佳实践,但这也可能对您有用:http://www.assembla.com/wiki/show/liftweb/Dependency_Injection

      【讨论】:

        【解决方案3】:

        同意萨沙。电梯方式应该可以工作:

        trait DataSource
        
        class MyDataSource extends DataSource
        
        object DataSources {
          @volatile var dataSource: () => DataSource = () => new MyDataSource
        }
        

        通过这种方法,您可以使用object 而不会失去可测试性。

        【讨论】:

        • 有趣。你能解释一下吗?
        • 抱歉,代码有错误。一定是var,不是def,我编辑的。
        • 使用这种方法,您实际上在 DataSources 变量中定义,该变量包含功能 - 数据源工厂。在生产代码中,您可以使用对象 DataSources 中定义的变量的默认值。但在测试中,您可以重新定义变量以返回您想要的任何内容。
        猜你喜欢
        • 2014-10-06
        • 2020-02-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        • 1970-01-01
        • 1970-01-01
        • 2017-12-28
        相关资源
        最近更新 更多