关于蛋糕模式的问题
问题描述:
让我们看看几个单独的DAO类OrderDAO
,ProductDAO
和CustomerDAO
,它们在数据库中存储/检索数据并共享单个实例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框架吗?
如何创建单独的OrderDAOImpl
和ProductDAOImpl
对象共享相同DataSource
实例而不是一个大DAOImpl
?
答
可能:
- 在编译时静态检查。
答
滤饼图案的优点是:
- 不像基于配置文件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.//
我简要阅读了关于蛋糕模式,并没有看到兴奋是关于什么。看起来比现有的DI容器复杂得多。 – Kevin 2011-04-15 17:06:48