0

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:

  1. Is my solution too flawed?
  2. If no what would be the most user friendly/convenient way to allow customization of properties?

P.S

  1. 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.
  2. 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.
Scis
  • 2,934
  • 3
  • 23
  • 37
  • You might find [Programmer's Stack Exchange](http://programmers.stackexchange.com/) a better fit for this type of conceptual question. – Bobulous Apr 27 '13 at 12:32

1 Answers1

0

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.

  1. DriverManager manages a list of drivers.
  2. Each driver must register itself to the DriverManager by calling its method registerDriver().
  3. Upon request for a connection, the getConnection(connectionString) method sequentially calls the drivers passing them the connectionString.
  4. 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:

  1. 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.
  2. Adding new analyzer just means adding a new call to the register() method. Complete decoupling.
Honza Zidek
  • 9,204
  • 4
  • 72
  • 118