3

Given the following Class and Service layer signatures:

public class PersonActionRequest {
    PersonVO person
    // ... other fields
}
public class MyServiceLayerClass {

   public void requestAction(PersonActionRequest request)
   {
       PersonVO abstractPerson = request.getPerson();
       // call appropriate executeAction method based on subclass of PersonVO
   }
   private void executeAction(PersonVO person) {}
   private void executeAction(EmployeeVO employee) {}
   private void executeAction(ManagerVO manager) {}
   private void executeAction(UnicornWranglerVO unicornWrangler) {}
}

As discussed here, java will select the best method based on type info at compile time. (Ie., it will always select executeAction(PersonVO person) ).

What's the most appropriate way to select the correct method?

The internet tells me that using instanceof gets me slapped. However, I don't see the appropraite way to select the method without explictly casting abstractPerson to one of the other concrete types.

EDIT: To Clarify - The VO passed in is a simple ValueObject exposed for web clients to instantiate and pass in. By convention it doesn't have methods on it, it's simply a data structure with fields.

For this reason, calling personVO.executeAction() is not an option.

Thanks

Marty

3
  • 4
    If it's any help, I wouldn't slap you for using instanceof there. Commented May 20, 2010 at 18:05
  • Are you using inheritance? Where is your inheritance tree? Commented May 20, 2010 at 18:06
  • You've got a highly procedural 'Struct + Manager' architecture. The answer to the question 'how can I take advantage of Object Oriented benefits like Polymorphism' is switch to an Object Oriented design domain. Adapt your VOs up front into working business objects. Is that the right answer for you? Maybe not. Zealotry aside, sometimes a procedural pattern is the right answer to a problem. What's wrong with instanceof? it's a procedural design pattern, not an OO one, so who cares about an OO principle like polymorphism? (and "It's slow" hasn't been true for many JVM versions now.) Commented May 20, 2010 at 19:05

5 Answers 5

5

If executeAction was a method in a base class or interface that was common to PersonVO, EmployeeVO, ManagerVO and UnicornWranglerVO, you could just call abstractPerson.executeAction() instead of having multiple overridden methods.

Sign up to request clarification or add additional context in comments.

1 Comment

Unfortunately, the VO is merely a Data Structure with fields only, no behaviours. I've updated the question to make this clearer.
4

Your principle obstacle to polymorphism here seems to be a 'dumb-struct' data object + 'manager class' service non-pattern. The "more polymorphic' approach would be for execute() to be a method that the various person implementations override.

Assuming that can't change, the way you do multiple dispatch in Java is with visitor-looking callbacks.

public interface PersonVisitor {
   void executeAction(EmployeeVO employee);
   void executeAction(ManagerVO manager);
   void executeAction(UnicornWranglerVO unicornWrangler);
}
public abstract class PersonVO {
public abstract void accept(PersonVisitor visitor);
}
public class EmployeeVO extends PersonVO {
@Override
public void accept(PersonVisitor visitor) {
  visitor.executeAction(this);
}
}

public class MyServiceLayerClass implements PersonVisitor {

   public void requestAction(PersonActionRequest request)
   {
       PersonVO abstractPerson = request.getPerson();
       abstractPerson.accept(this);
   }

   public void executeAction(EmployeeVO employee) {}
   public void executeAction(ManagerVO manager) {}
   public void executeAction(UnicornWranglerVO unicornWrangler) {}
}

Comments

2

You could change the way you are approaching the design and use a Visitor, passing the executor into the Person and have the person type determine which to call.

Comments

2

The Visitor pattern is often used to overcome Java lacking double-dispatch.

Comments

0

I would explicitly cast the abstractPerson. Not only does it ensure the JVM gets the right method, it makes it a hell of a lot easier to read and ensure you know what's going on.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.