Scala蛋糕图案鼓励硬编码依赖?
发布时间:2020-12-16 09:36:27 所属栏目:安全 来源:网络整理
导读:我还在尝试学习Scala的蛋糕图案。在我看来,它可以让您集中配置“组件”以及为这些组件提供默认实现(这当然可以覆盖)的优势。 然而,使用自我类型的特征来描述依赖关系似乎混合了关注点。组件(我认为)的目的是抽象出该组件的不同实现。但是组件中描述的依赖
我还在尝试学习Scala的蛋糕图案。在我看来,它可以让您集中配置“组件”以及为这些组件提供默认实现(这当然可以覆盖)的优势。
然而,使用自我类型的特征来描述依赖关系似乎混合了关注点。组件(我认为)的目的是抽象出该组件的不同实现。但是组件中描述的依赖关系本身就是一个实现问题。 例如,假设我有一个数据库包含小部件,一个注册表,允许我查找特定类型的小部件,以及一些使用注册表处理小部件的算法: case class Widget(id: Int,name:String) trait DatabaseComponent { def database: (Int => Widget) = new DefaultDatabase() class DefaultDatabase extends (Int => Widget) { // silly impl def apply(x: Int) = new Person(x,"Bob") } } trait RegistryComponent { this: DatabaseComponent => // registry depends on the database def registry: (List[Int] => List[Widget]) = new DefaultRegistry() class DefaultRegistry extends (List[Int] => List[Widget]) { def apply(xs: List[Int]) = xs.map(database(_)) } } trait AlgorithmComponent { this: RegistryComponent => // algorithm depends on the registry def algorithm: (() => List[Widget]) = new DefaultAlgorithm() class DefaultAlgorithm extends (() => List[Widget]) { // look up employee id's somehow,then feed them // to the registry for lookup def apply: List[Widget] = registry(List(1,2,3)) } } 现在你可以把它放在一些中央配置中: object Main { def main(args: Array[String]) { val algorithm = new AlgorithmComponent() with RegistryComponent with DatabaseComponent val widgets = println("results: " + algorithm.processor().mkString(",")) } } 如果我想要更改为不同的数据库,我可以通过更改我的mixin来轻松地注入它: val algorithm = new AlgorithmComponent() with RegistryComponent with SomeOtherDatabaseComponent 但是,如果我想在不使用数据库的不同的注册表组件中混合怎么办? 如果我尝试使用不同的(非默认)实现子类化RegistryComponent,则RegistryComponent将坚持要包含一个DatabaseComponent依赖项。而且我必须使用RegistryComponent,因为这是顶级的AlgorithmComponent需要的。 我错过了什么吗?在我的任何组件中使用自我类型的时刻,我声明所有可能的实现都必须使用相同的依赖关系。 有没有人遇到这个问题?蛋糕般的解决方法是什么? 谢谢! 解决方法
使用蛋糕模式,至少在
example I always go to,您应该将组件的界面定义与其默认实现分开。这干净地将接口的依赖与实现的依赖关系分开。
trait RegistryComponent { // no dependencies def registry: (List[Int] => List[Widget]) } trait DefaultRegistryComponent extends RegistryComponent { this: DatabaseComponent => // default registry depends on the database def registry: (List[Int] => List[Widget]) = new DefaultRegistry() class DefaultRegistry extends (List[Int] => List[Widget]) { def apply(xs: List[Int]) = xs.map(database(_)) } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- scala – 相当于Apache Spark RDD中的getLines
- angular – ng4 componentFactory将它放在DOM目标中
- 讨论创建基于WSE的报表打印服务及其实现
- 搭建 AngularJS+Ionic+Cordova开发APP----- win10环境运行一
- 使用量角器测试一个angularjs应用程序,当我使用它时,如何在
- angular工作原理
- 宝塔面板设置WordPress伪静态方法
- Kubernetes - - k8s - v1.12.3 Helm持久化部署 Redmine 集成
- soapui的webservice接口测试中参数设置
- 如何确保我的bash脚本尚未运行?