1

I am designing a treeNode class. While implementing the getPathToParentNode() and getPathFromParentNode() methods, I noticed that their functionality is essentially the same - they just operate on different data structures.

getPathToParentNode() recursively adds all parent nodes into a queue, and then creates the path using the queue iterator.

getPathFromParentNode() recursively adds all parent nodes into a stack, and then creates the path using the stack iterator.

To adhere to the DRY principle, I was thinking of extracting the duplicate code (recursively adding parents to a collection, and using the collection iterator to generate the path) into a separate function, and just passing it a queue from the first function and a stack from the second function.

// takes in a queue or a stack
// returns path to root node or path from root node respectively
List<ITreeNode<T>> getPath(Collection<ITreeNode<T>> pathCollection) {

    pathCollection.add(this);

    ITreeNode<T> parent = this.getParent();
    pathCollection.add(parent);

    while (parent.getParent() != null) {
        pathCollection.add(parent.getParent());
    }

    return new ArrayList<ITreeNode<T>>(pathCollection);
}

However, the resulting helper function doesn't feel right. I don't think it performs something independent/worthwhile enough to justify its existence. Furthermore, its objective changes based on the type of collection passed into it, and perhaps as a consequence of that, it is difficult to name.

Is such a method considered "good" in light of the principles of object-orientated design? What would be a better approach?

Edit:

Similar question regarding method extraction in general (but the answers do not address my specific case): Should I extract specific functionality into a function and why?

Hassaan
  • 111
  • 4
  • I think this one might come down to too much of an opinion based discussion. Personally I would probably have two separate functions and skip over DRY in this context in favour of clarity, but I wouldn't be at all put out if someone presented me with your code to work with either. – Jack Parkinson Jul 13 '17 at 07:49
  • 1
    Possible duplicate of [Should I extract specific functionality into a function and why?](https://softwareengineering.stackexchange.com/questions/166884/should-i-extract-specific-functionality-into-a-function-and-why) – gnat Jul 13 '17 at 08:29
  • That is about method extraction in general - I was asking about my specific case. – Hassaan Jul 13 '17 at 09:50

1 Answers1

2

You could have both implemented with a DQueue and just use an end selector to determine whether it is used FIFO or FILO, (First In First Out = Queue, First In Last Out = Stack). Then the two functions would become a single one with a direction specifier. Much simpler and no need for template specifiers.

Steve Barnes
  • 5,270
  • 1
  • 16
  • 18