0

我有一个为文本文件处理创建策略的引擎。这些文件有各种格式,引擎通过一系列策略传递文件来选择适当的策略,直到其中一个断言它可以解析它。

这不是典型的策略模式。它有点类似于服务定位器模式和责任链模式,并且可以合并其中任何一个方面的方面。

剥离后看起来有点像这样,尽管它目前是通过注入创建的:

        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,但我对其他基于反射和/或注释的解决方案持开放态度。

4

1 回答 1

0

好的,所以现在我认为我将执行以下操作,尽管远非理想,但至少将它与我的其他依赖管理联系起来。

向 Strat 接口添加一个 init 方法(实现应该自己注册);

public void init(Engine e);

在创建单例并调用注入方法的 GuiceModule 中创建并注入每个 Strat。

bind(ConcreteStrat1.class).asEagerSingleton();

这种方法存在一些问题,我希望可以解决。Strat 对象必须用 @Inject 注释它们的 init 方法,否则它将永远不会被调用。Eclipse 在插入方法存根时会有效地复制它,但据我所知,否则它是无法执行的。我不确定这将如何与“插入”策略一起使用,但我想在没有更好的情况下,我稍后会越过那座桥。

eta:我现在正在编写可以从数据库加载的 javascript 策略,这使得它可以很容易地用 JavascriptStrategyManager 插入

于 2013-10-11T13:38:55.727 回答