问题描述
我有一些设计问题,我想得到一些建议:我有几个类继承自同一个基类,每个可以接受相同的数据并以稍微不同的方式进行分析。
Analyzer
|
˪_AnalyzerA
|
˪_AnalyzerB
...
我有一个输入文件不能控制文件的格式),定义哪些分析器应该被调用及其参数。此外,它以相同的方式和其他类似的东西定义数据提取器(类似地,我的意思是这是一个可以有几个变体的操作)。
我有一个模块遍历文件中的不同分析器,并调用构建正确分析器的一些工厂。我有一个工厂,每个原型的输入文件可以定义,所以很好。
但是,如果我想扩展它,并添加一个新的类型分析器?
我正在考虑的解决方案是为每个工厂使用一个属性文件,这些工厂将以工厂名称命名,它将保存输入文件的定义之间的映射无论它要我执行什么,以及我用来执行操作的实际类。
这样我可以在运行时加载该类 - >验证它是实现正确的界面,然后执行它。
如果John Doe想要创建自己的分析器,那么他只需要在正确的文件中添加一个新的属性(我不太确定会是什么最好的策略是允许这种物业定制)。
所以简而言之:
- 如果不是最方便用户友好/便利的方式来允许自定义属性?
PS
- 不幸的是,我只限于使用仅在JDK类中构建的现有解决方案,所以我不能只是放在他们的SF上。
- 我希望这个问题不是不符合我只是不习惯让我的翅膀以这种方式剪裁,没有SF或其他一些帮助我实现一个优雅的解决方案。
如何方法被实现。最好的方法是观看源代码。
这个想法非常粗略的概括(它隐藏在很多私有方法中)。尽管没有链接的驱动程序列表,它或多或少地是一个责任链的实现。
- DriverManager管理驱动程序列表。
- 每个驱动程序必须通过调用其方法registerDriver()向DriverManager注册。
- 在请求连接时,getConnection(connectionString)方法顺序调用驱动程序通过它们的connectionString。
- 如果给定的连接字符串在其能力范围内,每个驱动程序都知道。如果是,则创建连接并返回。否则控制权将被传递给下一个驱动程序。
类比:
- drivers =您的具体分析器
- 连接字符串=要分析的文件的类型
优点:
- 没有必要明确地将分析器与他们想要的文件类型绑定。让分析仪自己决定是否能够分析文件。如果没有,则返回null(或异常或任何)告诉AnalyzerManager,应该询问该行中的下一个分析器。
- 添加新的分析器只是意味着添加一个新的调用register()方法。完全解耦。
I have a little design issue on which I would like to get some advice:
I have several classes that inherit from the same base class, each one can accept the same data and analyze it in a slightly different way.
Analyzer
|
˪_ AnalyzerA
|
˪_ AnalyzerB
...
I have an input file (I do not have control over the file's format) that defines which analyzers should be invoked and their parameters. Plus it defines data-extractors in the same way and other similar things too (in similar I mean that this is an action that can have several variations).
I have a module that iterates over different analyzers in the file and calls some factory that constructs the correct analyzer. I have a factory for each of the archetypes the input file can define and so far so good.
But what if I want to extend it and to add a new type of analyzer?
The solution I was thinking about is using a property file for each factory that will be named after the factories name and it will hold a mapping between the input file's definition of whatever it wants me to execute and the actual classes that I use to execute the action.
This way I could load that class at run-time -> verify that it's implementing the right interface and then execute it.
If some John Doe would like to create his own analyzer he'd just need to add a new property to the correct file (I'm not quite sure what would be the best strategy to allow this kind of property customization).
So in short:
- Is my solution too flawed?
- If no what would be the most user friendly/convenient way to allow customization of properties?
P.S
- Unfortunately I'm confined to using only build in JDK classes as the existing solution, so I can't just drop in SF on them.
- I hope this question is not out of line I'm just not used to having my wings clipped this way, not having SF or some other to help me implement an elegant solution.
Have a look at the way how the java.sql.DriverManager.getConnection(connectionString) method is implemented. The best way is to watch the source code.
Very rough summary of the idea (it is hidden inside a lot of private methods). It is more or less an implementation of chain of responsibility, although there is not linked list of drivers.
- DriverManager manages a list of drivers.
- Each driver must register itself to the DriverManager by calling its method registerDriver().
- Upon request for a connection, the getConnection(connectionString) method sequentially calls the drivers passing them the connectionString.
- Each driver KNOWS if the given connection string is within its competence. If yes, it creates the connection and returns it. Otherwise the control is passed to the next driver.
Analogy:
- drivers = your concrete Analyzers
- connection strings = types of your files to be analyzed
Advantages:
- There is no need to explicitly bind the analyzers with their type of file they are meant for. Let the analyzer to decide itself if it is able to analyze the file. If not, null is returned (or an exception or whatever) to tell the AnalyzerManager that the next analyzer in the row should be asked.
- Adding new analyzer just means adding a new call to the register() method. Complete decoupling.
这篇关于允许使用工厂最大的灵活/可扩展性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!