1

Im trying to come up with a solution where the class that processes a "message" is selected at runtime depending on the message type. I know that i can use something like this

if msg_type = "A"
  MsgAProcessor.execute(message);
else if msg_type = "B"
  MsgBProcessoror = execute(message);
....
....
....

I dont want to use the above approach as i dont want the code to know anything about the message types that i could be processing. I want to be able to in the future add a new message processor for a new message type. The solution i am thinking of at the moment is as follows

There are 3 message processors at the moment

MsgAProcessor
MsgBProcessor
MsgBProcessor

All three classes have a method called execute which will process the message in its own way. I have created an interface called MsgProcessor and added the execute() method in the interface.

Now i am having difficulty in knowing which message processor the caller should call without having to check the message type. For example, i cant do this

MsgProcessor proc = new MsgAprocessor() proc.execute()

The above will stil be required to be in an if statement as it needs to be called just after finding out the message type. I would also like to avoid instantiating using the implementation class type.

Is there a better way of achieving the same?

I want to be able to just call MsgProcessor.execute from the interface and have the runtime environment know which implementation class to call based on the message type.

ziggy
  • 15,677
  • 67
  • 194
  • 287

3 Answers3

5
  1. Have an interface Processor that has a method execute(). All your three MsgProcessors implement this.
  2. Have a separate class ProcessorControl that has a submit(String message) method. Whenever a new message comes, you simply do ProcessorControl.submit(message)
  3. Now ProcessorControl has a method addProcessor(Proccesor proc, String type) which adds the processors to a hashtable with type as the key. Hence each processor is now assigned with a type.
  4. In the submit method, just get hashtable.get(type).execute(proc)

This is a simple command pattern.

Suraj Chandran
  • 24,433
  • 12
  • 63
  • 94
  • 3
    A small but useful enhancement: Add a canExecute(String message) method in the Processor interface. In the ProcessorControl maintain a list (and not map) of Processors. When the message comes, then loop through the processors and call canExecute on each one of them. The one that returns true is the right one. This has the advantage that the code to check for message type is now in the processor which allows addition of new processors without any code change as long as the registering part is data-driven(using a property file, say) – rahulmohan Feb 24 '11 at 06:51
1

You could use a Map to map from message type to message processor. To decouple the implementations you could use a ServiceLoader: http://download.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html

Puce
  • 37,247
  • 13
  • 80
  • 152
1

Shortly you want to use dynamic class loading: Class.forName(THE CLASS NAME)

Your command may either contain the fully qualified class name or be mapped to it using properties file or naming convention. All implementations of your command should implement interface (as you already did). When you receive command get class name from it, then create command instance and call its execute method:

((Processor)Class.forName(className).newInstance()).execute()

AlexR
  • 114,158
  • 16
  • 130
  • 208