0

I would like to ask about best-practice how to hold and change a global state of application. I have a Parser (which now is a singleton) which among others have properties like

private String mode
private List<String> loadedResources

Then I have about ten modules with a very simple interface

ModuleOutput parse(String line, Path context) throws ModuleException;

Some modules do need to (some modules do not) get or set mode of the already processed file.

if (Parser.getInstance().getMode().equals("something") { ... }

or

Parser.getInstance().setMode("something");

which changes a state of the application and parser itself and other modules work with it.

Two modules (of ten) also want to add to loadedResources

if (!Parser.getInstance().getLoadedResources().contains(resource)) {
     Parser.getInstance().getLoadedResources().add(resource);
} else {
     // resource already loaded ...
}

but others not.

I do not like storing the global data in singleton and have modules reaching for it (because of tests and so on) but I do not even like that I would need to send all eventually needed information to modules which can process them... and then create big objects to return which would tell the Parser how to change the state (as well as the "globally needed" data can change over time), however it would probably be much cleaner. What are your suggestions? Thanks in advance.

4

1 回答 1

1

我只需创建一个 ParsingContext 对象,然后将模块可以更改/共享的所有内容移到那里。然后我会将这个 ParsingContext 传递给“ModuleOutput parse”的每个调用。这意味着 ParsingContext 将包含解析和资源的状态。通过这种方式,您可以清晰地定义模块可以共享和更改的内容。请注意,从范围的角度来看,这个 ParsingContext 的实例对 Singleton 来说要干净得多。单例的范围是全局变量。ParsingContext 的范围只是“parse”方法和 Parser 本身的调用。

回答更高层次的问题。我认为没有最佳实践来共享应用程序的全局状态。如果可能,目标始终是没有状态。

你可能会问如何在插件和框架之间共享状态。我的意见是,您应该使用尽可能少的对象(插件和框架入口点)共享的对象。没有 Singleton,因为通过创建 Singleton,您也可以将此状态暴露给应用程序的其余部分。

另一个想法是我会尽量减少“耦合”和显式状态。例如,您的模块实现包含方法 getPriority()。这样,您就可以订购插件。这迫使开发人员考虑所有可能的模块(即使是那些他没有实现的模块)并相应地设置优先级。相反,我会采用某种隐式排序。例如,通过创建解析器的几个明确定义的阶段并要求开发人员将模块“绑定”到该阶段。通过这样做,开发人员只考虑少量预定义的解析器阶段,而不是模块的任意顺序。

另外,在查看实现时,我会考虑为 Parser 类实现 State 设计模式和为模块实现 Chain of Responsibility 模式。但是很难说它是否可以实现,我必须深入挖掘源代码并编写一些单元测试来测试解析功能。

于 2013-05-05T18:19:43.000 回答