I am learning design patterns in Java and also working on a problem where I need to handle huge number of requests streaming into my program from a huge CSV file on the disk. Each CSV line is one request, and the first field in each line indicates the message type. There are 7 types of messages, each of which should be handled differently.
The code is something like the following:
class Handler {
private CustomClass {….}
Map<String, CustomClass> map = new HashMap<String, CustomClass>();
Public void runFile() {
// Read the huge CSV file with millions of records, line by line
// for each line, get the string before the first comma (say X)
switch (X) {
case 1 : myMethod1(….); break;
case 2 : myMethod2(….); break;
case 3 : myMethod3(….); break;
// ...
default: // ...
}
}
// Methods 1, 2, 3 declarations
}
Note 1: Some of the methods affect the map and others don't.
Note 2: Each request (method) uses different variables from the CSV line and executes a different logic.
Note 3: requests/methods are NOT connected; i.e. myMethod2()
does not logically follow myMethod1()
.
Now my question – What is an appropriate design pattern for this problem? Is it fine if I keep the whole logic in one class (similar to the code above) without changing?
Best Answer
I assume the code sample you show is just a simplified example and that the real problem is more complex, so as to deserve using a pattern.
CustomClass
an external class(*).Advantages: flexibility, if you create the map of processors outside the handler and pass it in the constructor, more processors can be added later and Handler will not need to be changed (for example to add a new case the switch control structure).
(*) You can achieve the same results having the interface and the processors as well as the customclass as inner classes/interfaces inside Handler, but it would pollute the solution a lot.
==> CustomClass.java <==
==> IMessageProcessor.java <==
==> ProcessorA.java <==
==> ProcessorB.java <==
==> ProcessorC.java <==
==> Handler.java <==
Note: You might wish to validate first whether the processor for the key x exists, and it it doesnt, fall back to a default processor, say, stored with key -1, or any other value garanteed not to exist in the CSV file.