For you who don’t know what inheritance is. Inheritance is a way to extend your code with functionalities from other code. Basically the same as parents with their children. All children inherit some characteristics from their parents and use that in their life.
Inheritance itself is not bad. As i mentioned earlier, you probably do this to increase code reusability. Code reusability is good as this also increases maintainability. Why is it a problem then? well…
Inheritance results in abstracting away implementation details
And that makes your code harder to understand. For you as the author everything might be perfectly clear, but will it still be clear after a few months? And what if another colleague, or worse, a new colleague picks up the code. I bet it will be a lot harder to see how everything works as methods could potentially be called multiple levels deep and you really have to dig in to see where everything is and how it all correlates.
In the example below we have a situation where we need to display multiple models with different unmappable datasets. This means each modal will be a separate component as the template is too different to put everything in one component.
The modal components use inheritance to encapsulate reusable modal logic. You could think of filtering, sorting, managing selections, saving etc. If you open the
modal-companies.component.ts you don’t immediately see this all this logic. As the inheritance is only one level deep and this is an easy example, it’s still sort of manageable. But things become really hard when you go into multiple levels of inheritance and logic gets more complicated. While things could become quite flexible and reusable you have to go trough multiple files to get an understanding of what is actually happening.
If you would refer back to my example about the child that inherits characteristics from their parents, it works exactly the same. If you know the kid without knowing the parents you might not be able to place some characteristics. You would have to do dig in and see or meet the parents in order to understand why the kid is what it is.
With code you don’t want that. In the ideal world, you want to quickly see/scan it, understand it, fix your stuff and move on. This is why I prefer a, more declarative, what you see is what you get solution over class inheritance.
What you see is what you get could be achieved by placing your code in a Service or a utility file. You can then call the Service from your Component which does the work for you. The nice thing is that when you open your component you immediately see which Services are injected, which functions of those services are called and what is returned by those functions.
As you can see we have removed the inheritance and moved the code that was in the
modal.ts class to the
modal-helper.service.ts service. Now, what i really like about this approach is that when you open one of the component files, you immediately see what functionalities that component has en where you can find it.
Just like class inheritance has a drawback, the above solution also has a drawback and that is that you have to write more code. However more code is not necessarily bad, especially in this case, as the above solution helps you to make your code easier to understand. And in my opinion, understandable code is good code.
While this is a somewhat opinionated post. The takeaway should be that code should be written in a way that it has the highest form of re-usability, maintainability and understandability. You almost always have to find a middle ground there. In that respect, i described a different solution which might suits your needs. Anyway, always remember:
Also check my other articles: