我有一个引擎,可以为文本文件处理创建策略。这些文件采用各种格式,引擎通过将文件传递给一系列策略来选择适当的策略,直到其中一个断言它可以解析它。
这不是经典的策略模式。它有点类似于服务定位器模式和责任链模式,并且可以包含其中任何一个方面。
剥离它看起来有点像这样,虽然它目前是用注射创建的:
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类在引擎中注册自己,但它们永远不会被类加载器加载,因此永远不会有机会注册。
我可以使用哪些替代方法来注册策略?虽然我目前正在使用DI,但我对其他基于反射和/或注释的解决方案持开放态度。
答案 0 :(得分:0)
好的,所以现在我想我会做以下事情,虽然远非理想,但至少将其与我的依赖管理的其余部分联系起来。
将一个init方法添加到Strat接口(实现应该自己注册);
public void init(Engine e);
在我的GuiceModule中创建并注入每个Strat,它创建单例并调用注入的方法。
bind(ConcreteStrat1.class).asEagerSingleton();
我希望这种方法有问题可以解决。 Strat对象必须使用@Inject注释它们的init方法,否则它将永远不会被调用。 Eclipse在插入方法存根时会有用地复制它,但是就我所知,它是无法执行的。我不知道这对于“掉入”策略会如何起作用,但我想如果没有更好的东西,我会稍后越过那座桥。
eta:我现在正在编写可以从数据库加载的javascript策略,这使得它可以使用JavascriptStrategyManager轻松插入