具有不同生命周期的对象的 Scala 蛋糕模式

标签 scala dependency-injection cake-pattern

我尝试在我的项目中使用蛋糕图案并且非常喜欢它,但是有一个问题困扰着我。

当所有组件都具有相同的生命周期时,蛋糕模式很容易使用。您只需定义多个特征组件,通过特征实现扩展它们,然后将这些实现组合在一个对象中,并通过自类型自动解决所有依赖关系。

但是假设您有一个可以作为用户操作的结果创建的组件(具有自己的依赖项)。该组件无法在应用程序启动时创建,因为它还没有数据,但它应该在创建时具有自动依赖解析。这种组件关系的一个例子是主 GUI 窗口及其复杂的子项(例如笔记本 Pane 中的选项卡),它们是根据用户请求创建的。主窗口是在应用程序启动时创建的,其中的一些子 Pane 是在用户执行某些操作时创建的。

这在 Guice 等 DI 框架中很容易完成:如果我想要某个类的多个实例,我只需注入(inject)一个 Provider<MyClass> ;然后我调用 get()该提供程序上的方法,以及 MyClass 的所有依赖项会自动解决。如果 MyClass需要一些动态计算的数据,我可以使用辅助注入(inject)扩展,但生成的代码仍然归结为提供者/工厂。相关概念、范围也有帮助。

但我想不出使用蛋糕图案的好方法。目前我正在使用这样的东西:

trait ModelContainerComponent {  // Globally scoped dependency
    def model: Model
}

trait SubpaneViewComponent {  // A part of dynamically created cake
    ...
}

trait SubpaneControllerComponent {  // Another part of dynamically created cake
    ...
}

trait DefaultSubpaneViewComponent {  // Implementation
    self: SubpaneControllerComponent with ModelContainerComponent =>
    ...
}

trait DefaultSubpaneControllerComponent {  // Implementation
    self: SubpaneViewComponent with ModelContainerComponent =>
    ...
}

trait SubpaneProvider {  // A component which aids in dynamic subpane creation
    def newSubpane(): Subpane
}

object SubpaneProvider {
    type Subpane = SubpaneControllerComponent with SubpaneViewComponent
}

trait DefaultSubpaneProvider {  // Provider component implementation
    self: ModelContainerComponent =>
    def newSubpane() = new DefaultSubpaneControllerComponent with DefaultSubpaneViewController with ModelContainerComponent {
        val model = self.model  // Pass global dependency to the dynamic cake
    }.asInstanceOf[Subpane]
}

然后我混合DefaultSubpaneProvider在我的顶级蛋糕中注入(inject)SubpaneProvider在所有需要创建子 Pane 的组件中。

这种方法的问题是我必须手动将依赖项(model 中的 ModelContainerComponent )从顶级蛋糕向下传递到动态创建的蛋糕。这只是一个简单的例子,但可以有更多的依赖关系,也可以有更多类型的动态创建的蛋糕。它们都需要手动传递依赖项;此外,某些组件接口(interface)的简单更改可能会导致多个提供商进行大量修复。

有没有更简单/更清洁的方法来做到这一点?这个问题在蛋糕图案中是如何解决的?

最佳答案

您是否考虑过以下替代方案:

  • 在 Scala 中使用内部类,因为它们会自动访问其父类成员变量。
  • 在基于参与者的应用程序中重构您的应用程序,因为您将立即受益于:
  • 层级/监督
  • 监听组件的创建/死亡
  • 访问可变状态时的正确同步

  • 拥有更多代码以提供更好的解决方案可能会有所帮助,您可以共享代码的编译子集吗?

    关于具有不同生命周期的对象的 Scala 蛋糕模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17525950/

    相关文章:

    java - 带继承的 Guice 注入(inject)

    go - Golang 中的工厂函数

    scala - 在 Scala 中使用 Cake 模式和函数之间的区别 - 为什么 Cake 模式有用?

    database - 类似于 iBATIS 的 Scala 数据库映射库

    scala - 如何使用 transformWith() 忽略失败的 future ?

    java - Spark 使用 sc.textFile 从 S3 读取文件(“s3n ://. ..)

    scala - 如何使用 Scala 的蛋糕模式来实现机器人腿?

    scala - 在惯用的 Scala 中更新大型数据结构

    c# - 如何在 ASP.NET Core 5 运行时动态重新配置服务?

    scala - 避免名称与 Cake Pattern 冲突