关于蛋糕模式的问题

问题描述:

让我们看看几个单独的DAO类OrderDAO,ProductDAOCustomerDAO,它们在数据库中存储/检索数据并共享单个实例DataSource(数据库连接工厂)。关于蛋糕模式的问题

为了创建DataSource实例并将其插入DAOs,我们通常使用Spring DI。现在我想在没有任何DI框架的Scala中这样做。

我读过有关cake pattern,它看起来像我应该做到以下几点:

trait DatabaseContext { val dataSource:Datasource } 

trait OrderDAO {this:DatabaseContext => 
    ... // use dataSource of DatabaseContext 
} 

trait ProductDAO {this:DatabaseContext => 
    ... // use dataSource of DatabaseContext 
} 

object DAOImpl extends OrderDAO with ProductDAO with DatabaseContext { 
    val dataSource = ... // init the data source 
} 

我是否正确理解了蛋糕的图案?

我可以使用蛋糕图案以不同方式实施这些DAOs吗?

它提供了像Spring这样的DI框架吗?

如何创建单独的OrderDAOImplProductDAOImpl对象共享相同DataSource实例而不是一个大DAOImpl

+0

我简要阅读了关于蛋糕模式,并没有看到兴奋是关于什么。看起来比现有的DI容器复杂得多。 – Kevin 2011-04-15 17:06:48

可能:

  • 在编译时静态检查。

滤饼图案的优点是:

  • 不像基于配置文件DI解决方案,匹配合同 实现是在编译时,这减少了 和兼容性类调查问题完成的。但是,许多DI引擎具有 替代代码内配置功能
  • 没有使用第三方库 。允许您使用该模式的自我类型注释是 本地语言功能。没有特殊的语法来检索 执行合同
  • 忘记指定一个 实现在 由另一个组件结果需要一个运行时错误的组件 - 只是检查本文 http://jonasboner.com/2008/10/06/real-world-scala-dependency-injection-di.html ,尽量不指定的一个组件或指定 特质,而不是一个具体的类中的任何蛋糕图案的 例子,甚至忘了初始化对应

但是需要一个部件的VAL,体验到这些优势,就需要更加严格地遵守到模式的体系结构 - 查看相同的文章,并注意包含实际合同和实现的包装特征。

你的例子似乎不是严格的蛋糕模式。在你的情况下,你可以使用继承为你的特性创建实现,并为每个DAO组件使用单独的类。在cake模式中,使用代码就像DAO代码一样是一个组件,组装依赖关系的代码将独立于它。

为了说明蛋糕模式,您必须在您的示例中添加使用类(域层或UI层)。或者你的DAO组件访问对方的功能,你可以单独说明你的DAO的蛋糕模式。

,使之短,

trait OrderDAOComponent { 
    val dao: OrderDAO 
    trait OrderDAO { 
     def create: Order 
     def delete(id: Int): Unit 
     //etc 
    } 
} 

trait OrderDAOComponentImpl extends OrderDAOComponent { 
    class OrderDAOJDBCImpl extends OrderDAO { 
     def create: Order = {/*JDBC-related code here*/} 
     def delete(id: Int) {/*JDBC-related code here*/} 
     //etc 
    } 
} 

//This one has a dependency 
trait OrderWebUIComponentImpl { 
    this: OrderDAOComponent => 
    class OrderWebUI { 
     def ajaxDelete(request:HttpRequest) = { 
      val id = request.params("id").toInt 
      try { 
       dao.delete(id) 
       200 
      } 
      catch { 
       case _ => 500 
      } 

     } 
    } 
} 

//This matches contracts to implementations 

object ComponentRegistry extends 
    OrderDAOComponentImpl with 
    OrderWebUIComponentImpl 
{ 
    val dao = new OrderDAOJDBCImpl 
    val ui = new OrderWebUI 
} 

//from some front-end code 
val status = ComponentRegistry.ui.ajaxDelete(request) 

更多关于你的榜样。我认为它可能更像蛋糕,如果:

trait DatabaseContext { val dataSource:Datasource } 

trait OrderDAOComponent {this:DatabaseContext => 
    trait OrderDAOImpl { 
     ... // use dataSource of DatabaseContext 
    } 
} 

trait ProductDAOComponent {this:DatabaseContext => 
    trait ProductDAOImpl { 
     ... // use dataSource of DatabaseContext 
    } 
} 

object Registry extends OrderDAOComponent with ProductDAOComponent with DatabaseContextImpl { 
    val dataSource = new DatasourceImpl //if Datasource is a custom trait, otherwise wrapping needed 
    val orderDAO = new OrderDAOImpl 
    val productDAO = new ProductDAOImpl 
} 

//now you may use them separately 
Registry.orderDAO.//