2011-07-07 38 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); 
     } 
}