集合的依赖注入

时间:2011-07-07 14:04:27

标签: java generics dependency-injection

我有一个与A一起使用的课程List<String>。但是这个课程之外的任何人都不需要知道它适用于字符串。但是,我还想提供类应该使用的具体实现List(通过依赖注入)。

A应如下所示

public class A {
  private ListFactory listFactory; //this gets injected from the outside

  public A(ListFactory listFactory) {
    this.listFactory = listFactory;
  }

  public void a() {
    List<String> = listFactory.createList();
    //...
  }
}

调用者类B就像这样

public class B {
  public void b() {
    ListFactory factory = new ArrayListFactory(); //we want class A to use ArrayList
    A a = new A(factory);
    //...
  }
}

ListFactory将是由ArrayListFactory实施以创建ArrayList的接口。

精髓: 我不希望B在某个地方提到String。而且我也不希望A在某处提及ArrayList

这可能吗? ListFactoryArrayListFactory将如何看待?

3 个答案:

答案 0 :(得分:1)

好像你写下了你所需要的一切。工厂看起来像:

interface ListFactory<K, T extends List<K>> {
    T create();
}

class ArrayListFactoryImpl implements ListFactory<String, ArrayList<String>> {
    public ArrayList<String> create() {
        return new ArrayList<String>();
    }
}

class Sample {
      public static void main(String[] args) {
          ListFactory<String, ArrayList<String>> factory = new ArrayListFactoryImpl();
          factory.create().add("string");
      }
}

答案 1 :(得分:1)

这比你做的更简单,我想:

public interface Factory {
    public <T> List<T> create();
}

public class FactoryImpl implements Factory {
    public <T> ArrayList<T> create() {
        return new ArrayList<T>();
    }
}

...
Factory f = new FactoryImpl();
List<String> strings = f.create();
...

答案 2 :(得分:0)

由于对问题有了更清晰的理解,这是另一次尝试:

interface ListFactory<T extends List> {
    T create();
}

class ArrayListFactoryImpl implements ListFactory<ArrayList> {
    public ArrayList create() {
        return new ArrayList();
    }
}

class ListWrapper<T> implements List<T> {
    private final List impl;

    public ListWrapper(List impl) {
        this.impl = impl;
    }

    public boolean add(T t) {
        if (!String.class.isAssignableFrom(t.getClass()))
            throw new RuntimeException("Aaaaa");
        return impl.add(t);
    }

    // so on...
}

class A {
    A(ListFactory factory) {
        List<String> stringsOnly = new ListWrapper<String>(factory.create());
    }
}

class Sample {
      public static void main(String[] args) {
          ListFactory<ArrayList> factory = new ArrayListFactoryImpl();
          new A(factory);
      }
}