DEV Community

Cover image for Code Smell 11 - Subclassification for Code Reuse
Maxi Contieri
Maxi Contieri

Posted on • Edited on • Originally published at maximilianocontieri.com

Code Smell 11 - Subclassification for Code Reuse

Code reuse is good. But subclassing generates a static coupling.

TL;DR: Favor composition over inheritance. Always. Period.

Problems

  • Coupling

  • Maintainability

Solutions

  • Favor composition.

Exceptions

  • If hierarchy follows the principle behaves like then it is safe.

Sample Code

Wrong

public class Rectangle {

    int length;
    int width;

    public Rectangle(int length, int width){
        length = length;
        width = width;
    }

    public int area(){
        return length * width;
    }
}

public class Square extends Rectangle {

     public Square(int size){
        super(size, size); 
    }

    public int area(){
        return length * length;
    }
}

public class Box extends Rectangle{    

}
Enter fullscreen mode Exit fullscreen mode

Right

abstract public class Shape{

    abstract public int area();
}

public final class Rectangle extends Shape {

    int length;
    int width;

    public Rectangle(int length, int width){
        length = length;
        width = width;
    }

    public int area(){
        return length * width;
    }
}

public final class Square extends Shape {

     int size;

     public Square(int size){
        size = size; 
    }

    public int area(){
        return size * size;
    }
}

public final class Box {

    Square shape;

    public Box(int size){
        shape = new Square(size); 
    }

    public int area(){
        return shape.area();
    }
}
Enter fullscreen mode Exit fullscreen mode

Detection

  • Overriding can issue warnings when subclassing concrete methods.
  • Deep Hierarchies (more than 3 levels) are also a clue of bad subclassing.

Tags

  • Composition

Conclusion

In legacy systems is very common to have Deep Hierarchies and method overriding, we need to refactor them and subclass by essential reasons and not implementative ones.

Relations

More info

Credits

Photo by Brandon Green on Unsplash


This article is part of the CodeSmell Series.

Last update: 2021/06/15

Top comments (1)

Collapse
 
pyrsmk profile image
Aurélien Delogu

I don't know well Java but isn't there interfaces in this language? Because extending abstract classes is still inheritance IMO, even if you can use them as interfaces. In Ruby we only have abstract classes too, so I can understand ahah.

In all cases, your Box class is an anti composition pattern. It should encapsulate an instance of Square instead of creating it in its constructor. It makes the code less testable ;)

AWS Q Developer image

Build your favorite retro game with Amazon Q Developer CLI in the Challenge & win a T-shirt!

Feeling nostalgic? Build Games Challenge is your chance to recreate your favorite retro arcade style game using Amazon Q Developer’s agentic coding experience in the command line interface, Q Developer CLI.

Participate Now

👋 Kindness is contagious

Discover fresh viewpoints in this insightful post, supported by our vibrant DEV Community. Every developer’s experience matters—add your thoughts and help us grow together.

A simple “thank you” can uplift the author and spark new discussions—leave yours below!

On DEV, knowledge-sharing connects us and drives innovation. Found this useful? A quick note of appreciation makes a real impact.

Okay