Ste*_*eve 9 java constructor guice
我可以通过几种不同的方式初始化复杂对象(注入依赖项和注入成员所需的设置),看起来都很合理,但各有利弊.我举一个具体的例子:
final class MyClass {
  private final Dependency dependency;
  @Inject public MyClass(Dependency dependency) {
    this.dependency = dependency;
    dependency.addHandler(new Handler() {
      @Override void handle(int foo) { MyClass.this.doSomething(foo); }
    });
    doSomething(0);
  }
  private void doSomething(int foo) { dependency.doSomethingElse(foo+1); }
}
Run Code Online (Sandbox Code Playgroud)
如您所见,构造函数执行了3项操作,包括调用实例方法.我被告知从构造函数中调用实例方法是不安全的,因为它绕过了编译器对未初始化成员的检查.即我可以doSomething(0)在设置之前调用this.dependency,这将编译但不起作用.重构这个的最佳方法是什么?
make doSomethingstatic并明确传入依赖项?在我的实际情况中,我有三个实例方法和三个成员字段都相互依赖,所以这似乎是很多额外的样板,使所有这三个静态.
移动addHandler并doSomething进入@Inject public void init()方法.虽然使用Guice是透明的,但它需要任何手动构造才能确保调用init(),否则如果有人忘记,对象将无法完全发挥作用.此外,这暴露了更多的API,这两者似乎都是坏主意.
包装嵌套类以保持依赖关系以确保其行为正常而不暴露其他API:
class DependencyManager {
  private final Dependency dependency;
  public DependecyManager(Dependency dependency) { ... }
  public doSomething(int foo) { ... }
}
@Inject public MyClass(Dependency dependency) {
  DependencyManager manager = new DependencyManager(dependency);
  manager.doSomething(0);
}
这会从所有构造函数中提取实例方法,但会生成一个额外的类层,当我已经有内部和匿名类(例如该处理程序)时,它会变得令人困惑 - 当我尝试这个时,我被告知要移动DependencyManager到一个单独的文件,这也是令人反感的,因为它现在是多个文件来做一件事.那么处理这种情况的首选方法是什么?
Effective Java中的Josh Bloch建议使用静态工厂方法,尽管我找不到像这样的情况的任何参数.但是,Java Concurrency in Practice中存在类似的情况,特别是用于防止this从构造函数中泄漏引用.适用于这种情况,它看起来像:
final class MyClass {
  private final Dependency dependency;
  private MyClass(Dependency dependency) {
    this.dependency = dependency;
  }
  public static createInstance(Dependency dependency) {
    MyClass instance = new MyClass(dependency);
    dependency.addHandler(new Handler() {
      @Override void handle(int foo) { instance.doSomething(foo); }
    });
    instance.doSomething(0);
    return instance;
  }
  ...
}
Run Code Online (Sandbox Code Playgroud)
但是,这可能不适用于您使用的DI注释.
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           2475 次  |  
        
|   最近记录:  |