Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Currently I have three classes and respective interfaces and respective builders:

  • Tree: the data structure (implemented in SimpleTree)
  • ProbabilityTree: is a Tree with added functionality to randomly select child nodes and to adjust the probability of selecting a node (implemented in ProbabilityTreeImpl).
  • DynamicTree: is a ProbabilityTree which dynamically constructs nodes when a requested node doesn't exist yet.

The client code needs Trees that support both random selection of nodes, as provided by ProbabilityTree, and the tree dynamically growing when yet unexisting nodes are requested, as provided by DynamicTree.

NOTE: Currently all three trees are immutable after having been build; for DynamicTree this means clients cannot add or remove nodes, but the tree itself can automatically change.

NOTE: See Github gist with the five Java classes for the code.

There are at least two issues with this design:

  1. DynamicTree is derived from ProbabilityTree, while conceptionally these two capabilities are unrelated (i.e. orthogonal).
  2. Using inheritance to add functionally is often considered "bad design" (correct me if I'm wrong here).

An alternative design would be to decouple ProbabilityTree and DynamicTree using something similar to the decorator and/or adapter pattern. Using Java's dynamic Proxy might enable "decorators" that extend the interface and that can decorate other Trees with extended interfaces; i.e.:

TreeDecorator implements InvocationHandler, ... {
    Tree adapted;
    ...
    Object invoke(Method method, Object[] args) {
        if( «this class can/should handle method» ) {
            return method.invoke(this, args);
        } else if ( «this.adapted can/should handle method» ){
            return method.invoke(adapted, args);
        }
    };
}

Again there are some issue's:

  1. Using Proxy makes the code more difficult to understand.

What shall I do? Use inheritance to extend functionallity, use dynamic proxy, or something else?

share|improve this question
2  
Why does DynamicTree extend ProbabilityTree if they are unrelated? –  Baqueta Aug 14 '12 at 13:20
1  
@Baqueta good question, I need trees that support both random selection of nodes, as provided by ProbabilityTree, and that dynamically grow when an yet unexisting node is requested, as provided by DynamicTree. To have both capabilities in the first design DynamicTree extends ProbabilityTree. –  Kasper van den Berg Aug 14 '12 at 13:34
2  
How about just putting the functionality shared by both ProbabilityTree and DynamicTree into a new interface? –  Baqueta Aug 14 '12 at 13:54
2  
I think I'm failing to understand why the DynamicTree and ProbabilityTree concepts are unrelated when it sounds like you want DynamicTree to be a specialised type of ProbabilityTree. Are you thinking that at some point you might have a variant of DynamicTree which isn't a ProbabilityTree? –  Baqueta Aug 14 '12 at 14:23
2  
I think that's a good idea - YAGNI should be applied here :-) –  Martijn Verburg Aug 14 '12 at 15:08

1 Answer 1

up vote 1 down vote accepted

I can think of 3 reasonable options, depending on what you really need (right now), and how complex your code is.

(What you currently call DynamicTree, I call DynamicProbabilityTree)

  1. If the only thing you really need is a DynamicProbabilityTree, and you feel like your code is simple enough to fit in one class, put all your code inside DynamicProbablityTree, and get rid of your other classes.

  2. If the only thing you really need is a DynamicProbabilityTree, but you feel like you code is too complex to fit into one class, keep your code for the tree structure in SimpleTree, and put the dynamic and probability code in DynamicProbabilityTree. I would recommend that DynamicProbabilityTree contain and delegate to a Tree instead of inheriting; inheriting would also work.

  3. If you really need a SimpleTree, ProbabilityTree (that is not dynamic), DynamicTree (that does not do probability), and DynamicProbabilityTree, use the Decorator pattern.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.