Java 在必须创建底层对象的实例时使用接口注入

Java 在必须创建底层对象的实例时使用接口注入,java,dependency-injection,interface-injection,Java,Dependency Injection,Interface Injection,我有一个接口来表示具有竞争性实现的数据结构。我需要在类中使用它,同时使类不必知道底层数据结构。在这个类中,我需要创建这个实现的几个实例。如何使用接口注入 class Foo { Map<String, IDataStructure> map = new HashMap<String, IDataStructure>(); public void addValue(String key, String value) { if(!map.contai

我有一个接口来表示具有竞争性实现的数据结构。我需要在类中使用它,同时使类不必知道底层数据结构。在这个类中,我需要创建这个实现的几个实例。如何使用接口注入

class Foo {
  Map<String, IDataStructure> map = new HashMap<String, IDataStructure>();

  public void addValue(String key, String value) {
        if(!map.containsKey(key)) {
             map.put(key, new SomeDataStructure(value));
        }
  }

}
并将其注入构造函数中

Foo(DataStuctureFactory factory)
Foo(DataStuctureFactory factory)
更改add方法

public void addValue(String key, String value) {
     if(!map.containsKey(key)) {
           map.put(key, factory.create());
     }
}
public void addValue(String key, String value) {
     if(!map.containsKey(key)) {
           map.put(key, factory.create());
     }
}

这是您可以做的:

在IDataStructure中定义add方法:

public interface IDataStructure {
    public void add(String value);
}
创建名为ListDataStructure的IDataStructure实现,如下所示:

public class ListDataStructure implements IDataStructure {

    private List<String> dataStructure = new ArrayList<String>();
    @Override
    public void add(String value) {
        dataStructure.add(value);
    }

}
class Foo {
  private Map<String, IDataStructure> map;

  public Foo(Map<String,IDataStructure> map) {
      this.map = map;
  }

  public void addValue(String key, String value) {
        if(map.containsKey(key)) {
             map.get(key).add(value);
        } else {
           /*handle what happens when data structure does not exist. Maybe thow an exception            
        }
  }

}
公共类ListDataStructure实现IDataStructure{
私有列表数据结构=新的ArrayList();
@凌驾
公共空添加(字符串值){
数据结构。添加(值);
}
}
创建名为SetDataStructure的IDataStructure的实现

public class SetDataStructure implements IDataStructure {

    private Set<String> dataStructure = new HashSet<String>();

    @Override
    public void add(String value) {
        dataStructure.add(value);
    }

}
public类SetDataStructure实现IDataStructure{
私有集数据结构=新HashSet();
@凌驾
公共空添加(字符串值){
数据结构。添加(值);
}
}
按如下方式修改您的Foo类:

public class ListDataStructure implements IDataStructure {

    private List<String> dataStructure = new ArrayList<String>();
    @Override
    public void add(String value) {
        dataStructure.add(value);
    }

}
class Foo {
  private Map<String, IDataStructure> map;

  public Foo(Map<String,IDataStructure> map) {
      this.map = map;
  }

  public void addValue(String key, String value) {
        if(map.containsKey(key)) {
             map.get(key).add(value);
        } else {
           /*handle what happens when data structure does not exist. Maybe thow an exception            
        }
  }

}
class-Foo{
私人地图;
公共食物(地图){
this.map=map;
}
public void addValue(字符串键、字符串值){
if(地图容器(图例)){
map.get(key)、add(value);
}否则{
/*处理数据结构不存在时发生的情况。可能有异常
}
}
}
如何注入受支持的数据结构的示例。请注意,不能动态定义数据结构。您需要使用受支持的数据结构实现在Foo中预填充映射

public class DataStructureExample {
    public static void main(String []args) {
        Map<String,IDataStructure> dataStrucures = new HashMap<String,IDataStructure>();

        //injecting different data structures into Foo
        dataStrucures.put("List", new ListDataStructure());
        dataStrucures.put("Set", new SetDataStructure());

        Foo foo = new Foo(dataStrucures);

        //add some value to a list data structure
        foo.addValue("List", "Value1");

        //add some valu to a set data structure
        foo.addValue("Set", "Value1");

    }
}
公共类数据结构示例{
公共静态void main(字符串[]args){
Map datastructures=newhashmap();
//向Foo注入不同的数据结构
put(“List”,新的ListDataStructure());
put(“Set”,新的SetDataStructure());
Foo-Foo=新的Foo(数据结构);
//向列表数据结构添加一些值
foo.addValue(“列表”、“值1”);
//向集合数据结构添加一些值
foo.addValue(“Set”、“Value1”);
}
}

我找到了一种使用接口注入的方法。创建一个抽象工厂

并将其注入构造函数中

Foo(DataStuctureFactory factory)
Foo(DataStuctureFactory factory)
更改add方法

public void addValue(String key, String value) {
     if(!map.containsKey(key)) {
           map.put(key, factory.create());
     }
}
public void addValue(String key, String value) {
     if(!map.containsKey(key)) {
           map.put(key, factory.create());
     }
}

“在这个类中,我需要创建这个实现的几个实例”。你能举例说明吗?我还是不明白这个问题。你所做的没有错,但是你不应该知道使用的是哪种数据结构,请看我的答案。顺便说一句,你的代码无法编译。我已将其编辑为complile。你的编辑没有多大意义。当工厂在任何给定的时间只能返回一个子类型时,为什么还要麻烦地创建工厂呢?为什么在Foo中使用地图。为什么不在Foo类中直接说IDataStructure dataStructure=newsomedatastructure,并在addValue方法中直接使用它呢?另外,如果不使用value参数,它有什么意义?尝试理解我的答案。但是
map.get(key)
将返回null,不是吗?注入发生在哪一点?否。map.getKey不会返回null,因为containsKey已经检查密钥是否存在。您的地图需要预先填充实例。假设您希望支持“列表”和“树”。然后,您需要创建这些实例,并在启动时将它们填充到映射中,以便在使用“列表”或“树”参数调用addValue方法时,实例化相应的数据结构。如果您有任何其他疑问,请告诉我。您能详细说明注入的步骤吗?编辑答案。注意,Foo类检查map.contains而不是!map.contains。如前所述,您不能动态创建数据结构实现。你需要准备好地图。向映射中添加实现确实是接口注入发生的地方。这回答了你的问题吗?