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。如前所述,您不能动态创建数据结构实现。你需要准备好地图。向映射中添加实现确实是接口注入发生的地方。这回答了你的问题吗?