views:

30

answers:

2

Imagine the following situation:

example

As may notice the Handler-childs and the Costumer-childs match each other. Each Handler has a method that takes a costumer.

Is there any good way true oo-ish to make sure that a Handler-implementation only takes a correponding Costumer-implementation or any childs of it?

Some examples:

  • Handler will take all Costumers
  • HandlerA will take CostumerA and CustomerAA but not CostumerB or Costumer
  • HandlerAA will only take CostumerAA

I came up with some ideas:

  • Make the Handler implementation check if it's a Costumer it knows
  • Create a dispatcher wich does the check

None of these seem good because always you need to hardcode the structure. If you add another subclass you need to change all logic that checks that which is quite bad.

+1  A: 

From your precise requirement, it seems that the only thing that each class or subclass must know is the corresponding class or subclass in the other hierarchy. I see no requirement to know its subclasses.

Several simple implementations could correspond to your need:

  • each class check in its method implementation if the other class corresponds, or is a subclass (I'm sure your OO language can test this).
  • each class register in its constructor call the corresponding class to the superclass ; in each method, that superclass checks if the corresponding class is equals (or a subclass) of that class.
  • generic typing (or templating) can also ensure that, at compile time, callers pass the appropriate subclass as a parameter

Please tell me if/where I'm wrong :-)


As Mark said, maybe you have a design smell .. :-) Having two hierarchies that mirror each other is probably not the best thing... We could help you fixing this if you want... :-)

KLE
+2  A: 

I'm not crazy about this design, but I can think of situations in which it might be appropriate.

A similar approach is taken by the Spring Validator interface. A solution analogous to theirs would be to make the Handler interface include a method boolean handles(Class c). Each Handler implementation, then, would have a simple method like

public class HandlerA extends Handler {
  boolean handles(Class c) {
    return (CustomerA.class.isAssignableFrom(c));
  }

  //etc.
}

Implementation would vary based on your language/platform, of course.

This way, the caller who calls the Handler is responsible for first checking whether it's the correct handler by calling this method.

JacobM