【问题标题】:Getting to Guice created objects from dumb data objects从哑数据对象到 Guice 创建的对象
【发布时间】:2009-07-21 06:26:56
【问题描述】:

我已经冒险并在我的最新项目中使用了 Guice。总体印象不错,但我遇到了一个我无法完全理解的问题。

背景:它是一个 Java6 应用程序,通过网络接受命令,解析这些命令,然后使用它们修改一些内部数据结构。这是我们公司生产的一些硬件的模拟器。我对内部数据结构所做的更改与命令对真实硬件的影响相匹配,因此数据结构的后续查询应该反映基于先前运行的命令的硬件状态。

我遇到的问题是命令对象需要访问那些内部数据结构。这些结构是由 Guice 创建的,因为它们根据被模拟的硬件的实际实例而有所不同。命令对象不是由 Guice 创建的,因为它们本质上是愚蠢的对象:它们接受文本字符串,解析它,然后调用数据结构上的方法。

让这一切正常工作的唯一方法是让这些命令对象由 Guice 创建并通过注入传递数据结构。感觉真的很笨重,并且完全膨胀了数据对象的构造函数。

我在这里错过了什么?

【问题讨论】:

    标签: java dependency-injection inversion-of-control guice


    【解决方案1】:

    依赖注入最适合接线服务。它可以用来注入值对象,但这可能有点尴尬,尤其是如果这些对象是可变的。

    也就是说,您可以使用 Providers 和 @Provides 方法来绑定您自己创建的对象。

    【讨论】:

    • 如果您的值对象因模拟的硬件而异,您可以编写一个工厂来创建它们,并让 Guice 将工厂注入需要它的代码中。换句话说,避免注入值对象的一种方法是创建一个生成值对象的服务。
    【解决方案2】:

    假设响应命令与响应 http 请求没有什么不同,我认为您走的是正确的道路。

    http 应用程序中常用的模式是将应用程序的逻辑包装到短期对象中,这些对象既有来自请求的参数,也有一些注入的后端。然后你实例化这样的对象并调用一个简单的、无参数的方法来完成所有的魔法。

    也许示波器能以某种方式激发您的灵感?查看into documentationsome code examples 了解技术细节。在代码中,它看起来不像那样。以下是这可能适用于您的情况:

    class MyRobot {
       Scope myScope;
       Injector i;       
    
       public void doCommand(Command c) {
          myScope.seed(Key.get(Command.class), 
          i.getInstance(Handler.class).doSomething();
       }
    }
    
    
    class Handler {
       private final Command c;
       @Inject
       public Handler(Command c, Hardware h) {
         this.c = c;
       }
    
       public boolean doSomething() {
         h.doCommand(c);
         // or c.modifyState(h) if you want c to access internals of h
       }
    }
    

    有些人不赞成这种解决方案,但我在过去至少两个不同项目中严重依赖 Guice 的代码中看到了这一点。

    当然,您将在构造函数中注入一些值对象,但如果您不将它们视为值对象,而是将其视为改变其行为的类的参数,那么这一切都是有意义的。

    这有点尴尬,有些人不赞成以这种方式注入价值对象,但我过去曾在一段时间内严重依赖 Guice 的项目中看到过这种情况,并且效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-10
      • 1970-01-01
      • 2023-01-25
      • 2014-01-14
      • 2011-03-14
      相关资源
      最近更新 更多