你如何在没有硬编码的情况下使用 Cake 模式进行依赖注入? [英] How do you do dependency injection with the Cake pattern without hardcoding?

查看:35
本文介绍了你如何在没有硬编码的情况下使用 Cake 模式进行依赖注入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚阅读并喜欢蛋糕模式文章.但是,在我看来,使用依赖项注入的一个关键原因是您可以改变由 XML 文件或命令行参数使用的组件.

I just read and enjoyed the Cake pattern article. However, to my mind, one of the key reasons to use dependency injection is that you can vary the components being used by either an XML file or command-line arguments.

Cake 模式如何处理 DI 的这一方面?我见过的例子都涉及静态混合特征.

How is that aspect of DI handled with the Cake pattern? The examples I've seen all involve mixing traits in statically.

推荐答案

由于混合特征在 Scala 中是静态完成的,如果您想改变混合到对象中的特征,请根据某些条件创建不同的对象.

Since mixing in traits is done statically in Scala, if you want to vary the traits mixed in to an object, create different objects based on some condition.

让我们举一个典型的蛋糕模式示例.您的模块被定义为特征,而您的应用程序被构造为一个简单的对象,其中混合了一堆功能

Let's take a canonical cake pattern example. Your modules are defined as traits, and your application is constructed as a simple Object with a bunch of functionality mixed in

val application =
    new Object
extends Communications
   with Parsing
   with Persistence
   with Logging
   with ProductionDataSource
application.startup

现在所有这些模块都有很好的自类型声明,定义了它们的模块间依赖关系,因此该行仅在所有模块间依赖关系都存在、唯一且类型良好时才编译.特别是,Persistence 模块有一个 self 类型,它表示任何实现 Persistence 的东西也必须实现 DataSource,一个抽象模块特征.由于 ProductionDataSource 继承自 DataSource,所以一切都很好,并且该应用程序构建线可以编译.

Now all of those modules have nice self-type declarations which define their inter-module dependencies, so that line only compiles if your all inter-module dependencies exist, are unique, and well-typed. In particular, the Persistence module has a self-type which says that anything implementing Persistence must also implement DataSource, an abstract module trait. Since ProductionDataSource inherits from DataSource, everything's great, and that application construction line compiles.

但是如果您想使用不同的数据源,指向某个本地数据库进行测试,该怎么办?进一步假设您不能仅使用从某些属性文件加载的不同配置参数重用 ProductionDataSource.在这种情况下,您要做的是定义一个扩展 DataSource 的新特征 TestDataSource,并将其混合.您甚至可以根据命令行标志动态执行此操作.

But what if you want to use a different DataSource, pointing at some local database for testing purposes? Assume further that you can't just reuse ProductionDataSource with different configuration parameters, loaded from some properties file. What you would do in that case is define a new trait TestDataSource which extends DataSource, and mix it in instead. You could even do so dynamically based on a command line flag.

val application = if (test)
  new Object
    extends Communications
      with Parsing
      with Persistence
      with Logging
      with TestDataSource
else
  new Object
    extends Communications
      with Parsing
      with Persistence
      with Logging
      with ProductionDataSource

application.startup

现在看起来比我们想要的要冗长一些,特别是如果您的应用程序需要在多个轴上改变其结构.从好的方面来说,您通常在应用程序中只有一个条件构造逻辑块(或者最坏的情况是每个可识别的组件生命周期一次),因此至少将痛苦最小化并与您的其余逻辑隔离.

Now that looks a bit more verbose than we would like, particularly if your application needs to vary its construction on multiple axes. On the plus side, you usually you only have one chunk of conditional construction logic like that in an application (or at worst once per identifiable component lifecycle), so at least the pain is minimized and fenced off from the rest of your logic.

这篇关于你如何在没有硬编码的情况下使用 Cake 模式进行依赖注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆