2011-07-07 39 views
1

我有一个类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(); 
    //... 
    } 
} 

而且这样

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

ListFactory主叫类B东西会是由ArrayListFactory实现创建ArrayList秒的接口。

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

这可能吗? ListFactoryArrayListFactory怎么样?

回答

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(); 
... 
+0

哇。谢谢!我甚至不知道这种语法。不得不看这个......这正是我想要的 – qollin

+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"); 
     } 
} 
+0

THX !但这并不完全,因为ArrayListFactoryImpl是由实现类“B”的“人”实现的。那个人不应该知道类“A”需要字符串...否则类A的用户必须知道A的实现细节(它使用字符串)。 – qollin

+0

你可以从其他地方将工厂传给B吗? –

+0

问题是,工厂目前知道两件事:字符串和ArrayList。没有人应该知道这两件事情,因为一个是A的实现细节,另一个是B的实现细节。但也许这是不可能的... – qollin

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); 
     } 
}