实例变量的构造函数/自引用

时间:2018-04-19 22:03:56

标签: java refactoring

如何最好地重构Java中的构造函数,它实例化成员/实例变量,需要引用将要构造/实例化的类?我想将构造函数中的依赖项作为参数传递,以启用对实例变量调用方法的方法的单元测试。

基本上归结为这样的事情:

final class Foo {
  private final Bar bar;
  ...

  Foo() {
    bar = new Bar(this);

    ...
  }
}

但是,所有依赖项都应该通过依赖注入/每个参数给出。

编辑:我的想法是将一个工厂作为参数添加到构造函数中,然后调用一个方法,该方法在方法中的createInstance方法中传递它,该方法使用实例变量:

final class Foo {
  private final BarFactory factory;

  Foo(BarFactory factory) {
    this.factory = Objects.nonNull(factory);
  }

  public void bla(String fooBar) { 
    final Bar bar = factory.create(this); 
    ...
  }
}

所以我可以嘲笑工厂。

1 个答案:

答案 0 :(得分:1)

我认为你在避免这种情况上走在正确的轨道上:

final class Foo {
  private final Bar bar;
  ...

  Foo() {
    bar = new Bar(this);

    ...
  }
}

对象的所有初始化都应该在构造函数中进行,因此您可以将未初始化的对象传递给Bar(),因为Foo()的构造可能会或可能不会完成。Bar()。当然,如果您传递引用,这不应该是一个问题,但仍然是一个不好的做法,正如您所提到的,您将无法轻松模拟Bar(),具体取决于您正在使用的模拟框架。 / p>

您有几个选择:

  1. 在您列出的方法中使用工厂。
  2. 工厂需要
  3. Lazy load Foo()
  4. 使用Setter Initialization
  5. 反转依赖关系。即,无论哪个代码依赖于Bar()需要Foo()所需的方法,都有Bar()个消费者 只需使用Foo()代替var x = Foo.blah()。这最终可能是最干净的领域,但也可能是最多的工作。
    • 即,将var x = Bar.blah()更改为import numpy as np from scipy.spatial import Voronoi def get_points(points) np_points = np.array(points) vor = Voronoi(np_points) fartest_point = None fartest_point_length = np.inf for vertex in vor.vertices: min_length = np.inf for p in points: length = norm(p-vertex) if length < min_length: min_length = length if min_length < fartest_point_length: fartest_point = vertex fartest_point_length = min_length return fartest_point points = [[2, 3, 5], [8, 2, 6], [10, 3, 5], [2, 3, 2], ...] point = get_points(points)
  6. 您有很多选择可供选择,并且没有任何“最佳”答案,只有您的域名才有意义。上面的任何一个工作,只看你写的问题,我会使用延迟加载或反转依赖。