Command pattern with too many classes - java

Our legacy code has a long code of if else blocks that depend on events and object type
if(event == A && objectType == O1){
.....
}
else if (event == A && objectType == O2){
....
}
else if (....)
....
....
With more and more conditions introducing, I was thinking of replacing this logic with Command pattern for each condition. But the number of classes required would be (no. of events) * (no. of object types). Is there any simpler way to refactor this code?

Create a class enclosing event and objectType, make it implement .equals() and .hashCode(). Create a generic class for each execution block too.
Then you'll be able to use a Map and a simple lookup will return what is needed to execute.

The pattern you may be looking for is often called double dispatching or sometimes Visitor pattern. http://en.wikipedia.org/wiki/Visitor_pattern
Create a set of classes for events and a set for object types. Create an interface
public interface VisitEvent {
public void visit(EventA eventA);
public void visit(EventB eventB);
// for each event class
}
Within the event class, you have to invoke the visit pattern on the object type class.
public class EventA {
public void visit(ObjectTypeParent otp) {
otp.visit(this);
}
}
Presuming that the object type classes inherit from a common class
public abstract class ObjectTypeParent implements VisitEvent {
public void visit(EventA eventA) {
// default code here
}
// same for each event visit from VisitEvent
}
then
public class ObjectType01 extends ObjectTypeParent {
public void visit(EventA eventA) {
// stuff you want done for this combination
}
// don't implement the ones that have common behavior
}

Related

Java: Is child overriding parent discouraged?

I was wondering if it's frowned upon that when designing an framework to be used by others, a class has some function as default behavior and expects its customers to override it if necessary. An example would be something like the following:
public class RecordProcessor<T extends Record> {
// ...
public void process() {
// process record logic
}
}
Consumers of this library creates their concrete classes to process their own records of type T.
Now I want to add a function called preProcess() to offer the ability for the consumers to preprocess their records. It would then look something like this:
public class RecordProcessor<T extends Record> {
// ...
public void process() {
preprocess();
// process record logic
}
public void preProcess() {
// By default no preprocessing
}
}
I know I can make preProcess an abstract function, but I dont want to due to a couple reasons:
Not all customers need to preprocess their records
We have a pipeline structure that autodeploys pushed code, so making RecordProcessor an abstract class would immediately break our customers' applications.
Is making preProcess do nothing in the parent class and let child classes override it considered bad practice? If not, what should the best way be to let customers know that they now have the power to preprocess the records? Through java docs?
One approach is to mark the public method as final (but this might also break existing apps) and allow protected hook methods to be overridden. For example:
public class RecordProcessor<T extends Record> {
// ...
public final void process() {
doPreProcess();
doProcess();
doPostProcess();
}
protected void doPreProcess() {
// By default no preprocessing
return;
}
protected void doProcess() {
// some default implementation
}
protected void doPostProcess() {
// By default no postprocessing
return;
}
}
Having some documentation should make it natural for other developers to recognize the optional extension methods.
I don't see anything wrong with having a hook method which does nothing. However, it should contain a return statement so static analysis tools won't complain.
UPDATE: in order to avoid breaking existing apps, if possible mark the existing method as deprecated and introduce a new method. For example:
public class RecordProcessor<T extends Record> {
// ...
public final void execute() {
doPreProcess();
doProcess();
doPostProcess();
}
#Deprecated - use execute() method instead.
public void process() {
doProcess();
}
protected void doPreProcess() {
// By default no preprocessing
return;
}
protected void doProcess() {
// some default implementation
}
protected void doPostProcess() {
// By default no postprocessing
return;
}
}
Prefer composition over inheritance. If you want your clients to add custom pre processing then do it by delegating to a separate objects.
public interface RecordPreProcessor<T extends Record>{
public void process(T record);
}
public class RecordProcessor<T extends Record> {
private RecordPreProcessor<T> recordPreProcessor = null;
public void setRecordPreProcessor(RecordPreProcessor<T> recordPreProcessor) {
this.recordPreProcessor = recordPreProcessor;
}
public void process() {
if (recordPreProcessor != null) recordPreProcessor.process(record);
// process record logic
}
}
No, overriding is not discouraged in Java.
The language allows overriding.
The language makes all methods overridable by default.
The Java class library includes examples of the same pattern.
Your approach is one reasonable way to allow subclasses to extend the behavior of their parent class. There are alternatives, such as passing a behavior as an object. However, there is no one true way.
One way you could improve your code is to mark preProcess() as protected. It's an implementation detail of the class. You don't want just anyone holding a RecordProcessor to decide they can call preProcess() by itself, right?
public class RecordProcessor<T extends Record> {
...
protected void preProcess() {
^^^^^^^^^
// By default no preprocessing
}
}
Another way to improve this is to consider whether you intend anyone to create an instance of the superclass RecordProcessor. If you don't, make the class abstract, to prevent that. The class name can express that, if you like, or your coding guidelines call for it.
public abstract class AbstractRecordProcessor<T extends Record> {
^^^^^^^^ ^^^^^^^^
...
protected void preProcess() {
// By default no preprocessing
}
}
One common way to document such methods is with the phrase "The default implementation does nothing. Subclasses may override this method ...". For example, below is the documentation for java.util.concurrent.FutureTask.done(). You can find more examples by searching for the first sentence of that phrase online.
public class FutureTask<V> implements RunnableFuture<V> {
...
/**
* Protected method invoked when this task transitions to state
* {#code isDone} (whether normally or via cancellation). The
* default implementation does nothing. Subclasses may override
* this method to invoke completion callbacks or perform
* bookkeeping. Note that you can query status inside the
* implementation of this method to determine whether this task
* has been cancelled.
*/
protected void done() { }
}
What I ended up doing- which I also thought was pretty good, inspired by #tsolakp, was simply creating a child class to RecordProcessor, called something like PreprocessRecordProcessor. This has no way of interfering existing code because nothing existing was touched. The class would something like this:
public class PreprocessRecordProcessor<T extends Record> extends RecordProcessor<T> {
// ...
public void process() {
preProcess();
super.process();
}
protected abstract void preProcess();
}
And if customers of this library would like to add their own logic they can simply extend this class and they'd be forced to provide pre-processing logic (as supposed to having the option to provide, which may result in unexpected results if they forgot to.)

Avoid using instanceof Patterns

I want to avoid the using of instanceof:
here is my case :
The definition of my Events classes are in a commons module :
public class Event1 extends AbstractEvent{
}
public class Event2 extends AbstractEvent{
}
public class Event3 extends AbstractEvent{
}
in another module called jms i have a listener that receive Event message from a queue :
public class MyMessageListener implements MessageListener {
#Override
public void onMessage(Message message) {
// CONVERT message to Event Object
if (event instanceof Event1) {
// Execute Processing 1
}
if (event instanceof Event2) {
// Execute Processing 2
}
if (event instanceof Event3) {
// Execute Processing 3
}
}
I want to avoid using instanceof and the best things for doing this is the visitor pattern with an execute method in the AbstractEvent and every leaf classes will implement it .
My problem is that in the common package i don't have access to the classes responsible for the processing . theses classes exist only in the jms module .
Is there any Tips or hint to do this (Advanced Visitor) or another pattern to do that
Put all possible behaviours to Map<Class, Runnable> and match event's type and Runnable type.
In such cases, the visitor Pattern can sometimes help. The visitor pattern is mainly suitable if your class hierarchy doesn't change much, because for each change in the class hierarchy you also must change the visitor (but that is also the case if you're using `instanceof').
To use the visitor pattern, you need to define a Visitor interface which contains a visit method for all types you want to visit:
interface Visitor {
visit(Event1 event);
visit(Event2 event);
visit(Event3 event);
}
first you want a common superclass which is the root for all classes you want to apply the visitor to. This superclass contains a method callVisitor:
public abstract class MyEvent extends AbstractEvent {
public abstract void visit(Visitor v);
}
public class Event1 extends MyEvent{
public void visit(Visitor v) {
v.visit(this); // calls visit(Event1)
}
}
public class Event2 extends MyEvent{
public void visit(Visitor v) {
v.visit(this); // calls visit(Event2)
}
}
public class Event3 extends MyEvent{
public void visit(Visitor v) {
v.visit(this); // calls visit(Event3)
}
}
Finally, you can create a visitor instance every time you need different behaviour based on the runtime type of the class:
public void onMessage(Message message) {
Visitor v = new Visitor() {
public void visit(Event1 event) {
// Execute Processing 1
}
public void visit(Event2 event) {
// Execute Processing 2
}
public void visit(Event3 event) {
// Execute Processing 3
}
}
event.visit(v);
}
The visitor pattern might be overkill in your situation, but I find it useful sometimes. The major advantage over using instanceof and other possible solutions is that it is typesafe: if you add a class to the hierarchy, the project will not compile until you added a visitor method to all visitors you defined.
As an alternative approach to the other answers, you could move the decision logic into your messaging configuration, so that each type of event is consumed by a MessageListener dedicated to processing only one type of Event. This will remove any "if" logic from your Consumer.
A caveat to this approach is that multiple consumers may process the events out of order. If this is an issue for your problem domain you may not wish to deal with the out-of-sequence issues yourself.
See JMS Selectors for more information
The advantages to this approach are:
Consumers are responsible for only one Event type (simplification)
You can add more Consumers independently based on event type (scalability)
You could have the AbstractEvent declare an abstract isOfType() method:
public abstract class AbstractEvent {
public abstract boolean isOfType( String type );
}
It would eliminate the instanceof's but not the if switching, though...
Cheers,

How to avoid using instanceof in this "visitor" pattern?

There are multiple Controller types which implement zero, one or many interfaces such as Updateable and Publishable
public class Controller {
private void doSomeProcessing() {
//do some processing
}
}
public class ArticleController extends Controller implements Publishable {
public void publish() {
this.doSomeProcessing();
//TODO: actually publish article
}
}
public class HeadlineController extends Controller implements Publishable, Updateable {
public void publish() {
this.doSomeProcessing();
//TODO: actually publish headline
}
public void update() {
this.doSomeProcessing();
//TODO: actually update headline
}
}
Some tasks in the implementation of these interfaces might contain code that is common to many or all Controller types, yet also some code that is unique to that one Controller type. Instead of having doSomeProcessing() in all of their implementations of Updateable (duplicate code), there can be a singleton overseer called Visitor (maybe not correct) that does all the updating and also calls the Controller's update.
public void update(Controller c) {
if (c instanceof Updateable) {
c.doSomeProcessing();
((Updateable)c).update(); //updateable code specific to this controller
}
}
Avoiding instanceof requires class casting which is also bad:
public void update(Updateable c) {
((Controller)c).doSomeProcessing();
c.update(); //updateable code specific to this controller
}
Note that instanceof in this case isn't as "bad" as most examples of "bad" usages of instanceof. That's because instead of acting like a switch statement, it's only 1 check to see whether or not it's legal to perform the method. Still, it seems wrong. Any ideas?

A good design pattern for a state machine with specific behavior

I am was having a simply state machine, which is now getting interference from a lot of special cases.
Initially:
void state(SomeObject o) {
doStep1();
doStep2();
doStep3();
}
Now, someobject had a field called type - say typeA, typeB, typeC. typeC demanded some special treatement.
void state(SomeObject o) {
doStep1();
doStep2();
if (o.type == typeC) { o.doFoo(); }
doStep3();
if (o.type == typeC) { o.doFoo(); }
}
Clearly this code is not extensible and fragile. I have a 4th type called typeD which would only add up more if-elses. Which pattern to use for such cases ? If I do use polymorphism, Assuming an interface SomeObject, which has 4 implementations for type A B C and D, I fear that A and B would have empty implementations for doFoo() which is not good. Any good design pattern ?
The state logic is as you already indicated inflexible. The problem can get even more sophisticated if, for example, for some objects we need to execute the operations in a different order (3->1->2).
As the behavior depends mainly on the SomeObject type, I believe that one "clean" approach would be to translate each object into a set of composable commands (Command pattern+Composite/Decorator).
/* Declare an interface for executing an operation */
public interface Command
{
public void execute();
public Command setNext();
public Boolean hasNext();
}
/* Abstract class providing compose-ability and chaining behavior for its children.
*/
public abstract class BaseCommand implements Command
{
private Command next;
public Boolean hasNext()
{
return next != null;
}
public Command setNext(Command nextC)
{
next = nextC;
return nextC;
}
public void execute(){
executeImpl();
if(hasNext()) next.execute();
}
public abstract void executeImpl();
}
Now, you can define a set of commands corresponding to a particular processing (each would map directly to a particular "line"/step of your state method).
public class Step1Command extends BaseCommand
{
// If we need access to the SomeObject instance we can define a dependecy on it
// ex. through a constructor
//The necessary processing goes here
public void executeImpl(){
doStep1();
}
}
Finally, you need to translate your objects into a set of commands, this can be achieved through a factory class:
public class CommandFactory
{
//The necessary processing goes here
public Command create(SomeObjectA typeA){
Command firstCommand = new Step1Command(typeA);
Command secondCommand = new Step2Command(typeA);
//....
Command lastCommand = new StepXCommand(typeA);
//We can easily switch the order of processing for a particular object
fistCommand.setNext(secondCommand)
//...
.setNext(lastCommand);
return firstCommand;
}
}
How would look your code now ?
CommandFactory cFactory = new CommandFactory();
void state(SomeObject o) {
Command command = cFactory.create(o);
command.execute();
}
So, what's the added value (as this may look like an overkill) ?
The processing depending on object type is moved away from the state method. Method overloading + inheritance should allow you to bypass if/elses.
You can easily switch the order of the necessary processing (), which makes the logic more flexible.
Adding new SomeObject implementations processing won't alter your existing code ( Maintainability+Extensibility)

Java polymorphic methods

In Java i have abstract class named Operation and three its subclasses called OperationActivation, OperationPayment and OperationSendEmail.
ADDED FROM COMMENT: Operation* objects are EJB Entity Beans so I can't have business logic inside them.
No I want to create processor class like this:
public class ProcessOperationService {
public void processOperation(Operation operation) {
out.println("process Operation");
process(operation);
}
public void process(OperationActivation operationActivation) {
out.println("process Activation");
}
public void process(OperationPayment operationPayment) {
out.println("process Payment");
}
public void process(OperationSendEmail operationSendEmail) {
out.println("process OperationSendEmail");
}
}
Processing each operation requires different logic so I want to have three different methods , one for each operation.
Of course this code doesn't compile. Am I missing something or it can't be done that way?
You are mixing up overloading and polymorphic method handling. When you overload methods based on the parameter type, that is static polymorphism. Those methods should be called from code that knows at compile-time what the type is. You could possibly do the following, but it wouldn't be clean object-oriented code:
public class ProcessOperationService {
public void processOperation(Operation operation) {
out.println("process Operation");
if (operation instanceof OperationActivation)
process((OperationActivation)operation);
else if (operation instanceof OperationPayment)
process((OperationPayment)operation);
...
}
public void process(OperationActivation operationActivation) {
out.println("process Activation");
}
...
}
It would be much better to let the automatic run-time polymorphism work, by doing as Brian Agnew suggested, and making process be a method of each Operation subtype itself.
Shouldn't your Operation* objects be doing the work themselves ? So you can write (say)
for (Operation op : ops) {
op.process();
}
You can encapsulate the logic for each particular operation in its own class, and that way everything related to OperationPayment remains in the OperationPayment class. You don't need a Processor class (and so you don't need to modify a Processor class everytime you add an Operation)
There are more complex patterns to enable objects to mediate wrt. what they need to execute, but I'm not sure you need something that complex at this stage.
Assumption: Operation* objects are subclasses of Operation
Unless the processOperation(Operation) method is performing some common functionality, you could just remove it and expose the process(Operation) methods.
The Command Pattern (JavaWorld Explanation) might be useful, but it's tricky to tell exactly what properties you want from your question.
The problem with the code is that any object that matches one of the process(Operation*) methods will also match the process(Operation) method. As there are 2 methods that can be used, the compiler is warning you of an ambiguous situation.
If you really want/need the code above, I would suggest implementing the process(Operation*) methods, and modify the process(Operation) method so it is called processCommon(Operation). Then, the first thing each process(Operation*) does is call processCommon.
Alternatively, you can code exactly as Avi said, using instanceof comparisons.
Neither is ideal, but it will accomplish what you want.
So you have an abstract class called 'Operation' and it has 3 classes extending it. Not sure if this is what you are after but I'd imagine it be designed something like this:
Operation.java
public abstract class Operation {
public abstract void process();
}
OperationActivation.java
public class OperationActivation extends Operation {
public void process() {
//Implement OperationActivation specific logic here
}
}
OperationPayment.java
public class OperationPayment extends Operation {
public void process() {
//Implement OperationPayment specific logic here
}
}
OperationSendEmail.java
public class OperationSendEmail extends Operation {
public void process() {
//Implement OperationSendEmail spepcific logic here
}
}
ProcessOperationService.java
public class ProcessOperationService {
public void processOperation(Operation operation) {
out.println("process Operation");
operation.process();
}
}
Won't the Visitor pattern be of use here ?
The class Operation can declare an "accept" method that takes a Visitor object and the subclasses can have provide the implementation :
public interface IOperationVisitor {
public void visit (OperationActivation visited);
public void visit (OperationPayment visited);
public void visit (OperationSendEmail visited);
}
abstract class Operation {
public void accept(IOperationVisitor visitor)();
}
class OperationActivation extends Operation {
public void accept(IOperationvisitor visitor) {
visitor.visit(this);
}
}
Similarly define "accept" method for classes OperationPayment and OperationSendEmail ..
Now your class can implement the visitor :
public class ProcessOperationService implements IOperationVisitor {
public void processOperation(Operation operation) {
operation.accept(this);
}
public void visit (OperationActivation visited) {
// Operation Activation specific implementation
}
public void visit (OperationPayment visited) {
// OperationPayment specific implementation
}
public void visit ((OperationSendEmail visited) {
// (Operation SendEmail specific implementation
}
}

Categories