0

我有一個創建文本文件處理策略的引擎。這些文件採用各種格式,引擎通過將文件傳遞給一系列策略來選擇適當的策略,直到其中一個策略聲明它可以解析它。使用DI創建可插拔StrategyFactory

這不是經典的戰略模式。它與服務定位器模式和責任鏈模式有些相似,並可能包含其中的任何方面。

剝離下來,它看起來有點像這樣,儘管它目前與注射創建:

 public class EngineImpl { 

      private Set<Strat> strategies = new HashSet<Strat>(); 

      public EngineImpl(){ 
       registerStrategy(new ConcreteStrat1()); 
       registerStrategy(new ConcreteStrat2()); 
      } 

      public void registerStrategy(Strat strat){ 
       strategies.add(strat); 
      } 

      public Strat getStrategy(SomeClass input){ 
       for (Strat s: strategies) 
        if (s.canParse(input) 
         return s; 
       return null; 
      } 

     } 

既然這樣,問題是,EngineImpl必須知道在編譯的時候所有可用的策略,這個工作我希望能夠在不更改EngineImpl代碼的情況下部署新策略。我已經在其他地方尋找了在Java中執行此操作的選項,並提出了空白。我考慮讓Strat類向Engine註冊,但是它們永遠不會被類加載器加載,所以絕不會有機會註冊。

我可以使用哪些替代方法來註冊策略?儘管我目前正在使用DI,但我仍然接受其他基於反射和/或註解的解決方案。

回答

0

好的,所以現在我想我會做以下事情,雖然遠非理想,但至少應該與我的其他依賴管理層相結合。

向Strat接口添加一個init方法(實現方法需要自己註冊);

public void init(Engine e); 

創建並注入每個Strat在我的GuiceModule中創建單例並調用注入的方法。

bind(ConcreteStrat1.class).asEagerSingleton(); 

這個方法有問題,我希望可以解決。 Strat對象必須使用@Inject註釋它們的init方法,否則它將永遠不會被調用。 Eclipse在插入方法存根時有用地複製了它,但是據我所知,它無法執行。我不知道這將如何與「投入」策略一起工作,但我想在沒有更好的事情的情況下,我會在稍後穿過那座橋。

eta:我現在正在編寫可以從數據庫加載的javascript策略,這使得它可以通過JavascriptStrategyManager輕鬆插入