Scala蛋糕图案和依赖性碰撞
发布时间:2020-12-16 19:07:53 所属栏目:安全 来源:网络整理
导读:我正在使用Cake Pattern在 Scala中实现依赖注入,但正在依赖冲突.由于我找不到具有这种依赖关系的详细示例,这里是我的问题: 假设我们有以下特征(有2个实现): trait HttpClient { def get(url: String)}class DefaultHttpClient1 extends HttpClient { def g
我正在使用Cake Pattern在
Scala中实现依赖注入,但正在依赖冲突.由于我找不到具有这种依赖关系的详细示例,这里是我的问题:
假设我们有以下特征(有2个实现): trait HttpClient { def get(url: String) } class DefaultHttpClient1 extends HttpClient { def get(url: String) = ??? } class DefaultHttpClient2 extends HttpClient { def get(url: String) = ??? } 和以下两个蛋糕模式模块(在本示例中,它们都是依赖于我们的HttpClient功能的API): trait FooApiModule { def httpClient: HttpClient // dependency lazy val fooApi = new FooApi() // providing the module's service class FooApi { def foo(url: String): String = { val res = httpClient.get(url) // ... something foo specific ??? } } } 和 trait BarApiModule { def httpClient: HttpClient // dependency lazy val barApi = new BarApi() // providing the module's service class BarApi { def bar(url: String): String = { val res = httpClient.get(url) // ... something bar specific ??? } } } 现在,当创建使用这两个模块的最终应用程序时,我们需要为这两个模块提供httpClient依赖关系.但是,如果我们要为每个模块提供不同的实现呢?或者简单地提供不同的依赖配置的不同实例(例如使用不同的ExecutionContext)? object MyApp extends FooApiModule with BarApiModule { // the same dependency supplied to both modules val httpClient = new DefaultHttpClient1() def run() = { val r1 = fooApi.foo("http://...") val r2 = barApi.bar("http://...") // ... } } 我们可以在每个模块中以不同的方式命名依赖关系,使用模块名称作为前缀,但是这样做并不麻烦,而且如果我们自己没有完全控制模块,那么它们将不起作用. 有任何想法吗?我是在曲解蛋糕模式吗? 解决方法
你得到的模式正确,你刚才发现了它的重要限制.如果两个模块依赖于一些对象(例如HttpClient),并且恰好在同一个名称下声明它(如httpClient),则游戏结束 – 您将不会在一个Cake中单独配置它们.要么有两个蛋糕,像丹尼尔提供或改变模块的来源,如果你可以(正如托默·加布尔暗示).
每个解决方案都有其问题. 有两个蛋糕(丹尼尔的建议)看起来很好,只要他们不需要一些共同的依赖. 重命名一些依赖项(只要有可能)迫使您调整所有使用这些依赖项的代码. 因此,有些人(包括我)喜欢解决这些问题的解决方案,比如使用简单的旧构造函数,完全避免使用Cake.如果你测量它,它们不会增加太多的代码(蛋糕已经很冗长),而且它们更加灵活. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |