Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How aggressively should I subclass to keep DRY? [closed]

This question occurred to me when an answer was proposed to another question I asked. Suppose I have a base class

public abstract class BaseClass {}

with some decent number of derived classes- let's say more than half a dozen. Most of those derived classes share no similarity beyond what they inherit from the base class, but two of them have a similarity like so

public class OneOfMyDerivedClasses : BaseClass
{
    public string SimilarProperty {get; set;}
    //Other implementation details
}

public class AnotherOneOfMyDerivedClasses : BaseClass
{
    public string SimilarProperty {get; set;}
    //Other implementation details, dissimilar to those in OneOfMyDerivedClasses
}

That's it. That's the only similarity that any of the subclasses share beyond what was inherited from BaseClass. In my actual application I've solved this with an interface IHaveSimilarProperty defining the single SimilarProperty property, as all I care about is that an object implements said interface in use. But since I have duplication, should I be defining an intermediate base class for these two derived classes to inherit from, ie

public abstract IntermediateBaseClass : BaseClass
{
    public string SimilarProperty {get; set;}
}

I could also combine both approaches, decorating the intermediate class with the interface...

So my question is around whether or not this is sufficient duplication to warrant an intermediate base class in terms of OOP best practices. Should I aggressively eliminate all duplication at every turn or should I take a more pragmatic approach? If the latter, what are the rules of thumb that would push me to choose one approach over the other?

like image 357
joelmdev Avatar asked Dec 12 '13 14:12

joelmdev


3 Answers

Any design pattern can be taken to extremes. Here's some general guidelines I would use when deciding whether or not to subclass:

  • Is the amount of code relatively large (>10 lines)?
  • Will the code require periodic changes (e.g. business rules)
  • Will I need to use polymorphism (does it make sense to use the base class or interface instead of one of the subclasses)

In your case, since the only similarity seems to be a property with the same name in both classes, it probably isn't worth it to subclass.

like image 128
D Stanley Avatar answered Nov 13 '22 06:11

D Stanley


You should decide on subclassing based on the common semantic of your classes, not merely on their common attributes. Sharing a common property is not enough to warrant an intermediate common subclass, but sharing a common semantics would definitely be enough.

Here is an example: a Rectangle and a Circle classes may have a property called Center, but it does not mean that the two classes should have a common subclass (apart from the abstract Shape, which may not necessarily have a Center). In this situation, an interface IWithCenter fits a lot better. Similarly, a Label and an TextField may have a property Text, but in this case even a common interface would be unwarranted.

like image 22
Sergey Kalinichenko Avatar answered Nov 13 '22 06:11

Sergey Kalinichenko


It's fine to aggressively eliminate duplication at every turn, but your #1 tool for doing so is composition, not inheritance. Use inheritance when you need polymorphism, use composition when you need reuse.

...but if the "duplication" in question is just one property, then maybe don't worry about it. The golden rule of refactoring is that each refactoring should make your life better instead of worse. If it doesn't, you're doing it wrong.

like image 2
David Seiler Avatar answered Nov 13 '22 05:11

David Seiler