1

There is a parent class with a method which many children use but many children extend the method, what is the best way to extend it without violating DRY?

Here are my 2 current solutions:

1: The parent has a method which calls the reusable code which is relevant for all subclasses (do_this), then it calls a class specific method which all subclasses override. e.g.

    class Parent(object):
        def method(self):
            self.do_this()
            self.do_this_unique_to_class()

        def do_this(self):
            print 'every child wants to print this'

        def do_this_unique_to_class(self):
            pass

    class Child(object):
        def do_this_unique_class(self):
            print 'Only class Child wants to print this'

2: Just use super and every child overrides the parents method. I don't like this solution as much. e.g.

    class Parent(object):
        def do_this(self):
            print 'every child wants to print this'

    class Child(object):
        def do_this(self):
            # call parents do_this
            super(Child, self).do_this()
            # then extend it
            print 'Only class Child wants to print this'
1
  • Rather than use inheritance, why not simply pass do_this_unique_class in to method as a parameter?
    – David Arno
    Commented Dec 10, 2015 at 9:03

3 Answers 3

1

The problem with your solution #1 is that you will never know if you later need some of do_this_unique_class done before do_this.

I would do something a bit different, but somewhat along the lines of #2, by splitting up the do_this method in the parent into methods that the parent makes available for the children and then have the children's 'do_this' method call the methods they need and add in their own logic.

2
  • But then, each child has almost the same flow of calls in their do_this method, violating DRY. And there is also question of specific order of calls to the methods. Who is going to enforce those if child can call them in any order?
    – Euphoric
    Commented Dec 10, 2015 at 12:52
  • "almost the same flow of calls" If it is different for each child then you don't really repeat yourself do you? Calling the same method in different places ins't a violation of DRY, copying the logic in that method around in different places because you need slight variations in the lgoic around it is.
    – Bent
    Commented Dec 10, 2015 at 13:09
1

The second is better. It means you don't have methods in the parent class that have no contextual meaning for that class and which don't do anything if called from instances of that class.

If the child class has the same behaviour as the parent class but implements it differently just override the implementation in the child class. The rest of the system won't care so long as the behaviour is as expected. That keeps polymorphism and encapsulation, the user of the object knows it will carry out some behaviour but doesn't care how and they don't need to know if they are actually using an instance of the parent or child class. Remember that methods are contracts with the rest of the system, I will do this behaviour for you if you ask me, but I won't tell how I'm going to do it. The method name should indicate the behaviour the object will carry out for the rest of the system. If both the parent and child carry out the same behaviour they should advertise this using the same method.

Make sure though that from the perspective of the user of the object the behaviour is consistent. Never override a method that produces a different behaviour depending on whether it is the parent or child object being called (ie never make a "print_to_console" method suddenly start sending out emails instead)

0

Neither solution is clearly superior over the other and both have their uses.

The first solution works best if the Parent class implements an algorithm that can be extended at one or more places (not necessarily right at the beginning or the end) and the extensions should only be inserted at those defined extension points.

The second solution is typical for the case where the Parent class does not foresee any extension to the algorithm (in a language where methods are virtual by default), or when the Parent class provides a default implementation that some children want to re-use in addition to their own modifications to that default.
Solution 2 is usually preferred if children can replace the method of the parent or add extra steps in front and/or after it, but they are not supposed to add steps in the middle of the operation that the Parent implementation does.

Your Answer

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

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