Register to get access to free programming courses with interactive exercises

Composition instead of inheritance JS: Dive into Classes

Inheritance is one of the most controversial OOP mechanisms. The more we learn about it, the more pitfalls we encounter. Not only does it add an incredible number of new concepts and behaviors to the code, but it also has fundamental flaws. Everything should be more or less clear with the first; in all the previous lessons we were only considered rethinking how we work with classes, but there's lots to be done with the second.

The key problem with hierarchies is that our world is not hierarchical. Any classification always relies on a particular attribute that interests us at a particular point in time. And the same classification becomes useless if another attribute is taken. This is clearly visible in online stores, which have sophisticated filters for selecting goods: grouping by manufacturer, area of application, child safety, and so on. Each situation will have its own structure.

Take the concept of a User. Articles on inheritance often like to show user hierarchies, giving developers the belief that this is the way the world works. Let's try to figure out what characteristics can be used to build a hierarchy of users:

  • By gender (MaleUser, FemaleUser)
  • Based on authentication (User, Guest)
  • By role (Admin, Member)
  • By type of job (Marketer, SalesManager, Programmer, Tester, Player)
  • By group (UserFromCanada, UserWhoLikesTennis)
  • By source (UserFromFacebook, UserFromGithub)
  • By type of storage (SQLUser, LocalStorageUser)
  • ...

All of this can and will occur within even just one program. Depending on what task we're looking at, we may need different representation. Inheritance doesn't give that freedom; it actually binds us to a specific structure that can't be changed. The only way out within this paradigm becomes even more inheritance. As a result, we'll end up with a combination of all possible behaviors that will be encountered in the program – hierarchies with dozens or hundreds of classes. Don't forget that all this has to somehow coordinate with the interfaces, which can also extend each other.

The solution could have been multiple inheritance, but as the life of some languages (C++) has shown, multiple inheritance makes things even more complicated. That's why he was rejected by everyone who could.

Eventually, developers formed a common position with respect to inheritance: composition instead of inheritance. If you try googling this phrase, you'll be shown an incredible number of articles on the subject. We already studied this approach in the JS: Polymorphism course. It comes down to a more competent division of responsibility in the application and the delegation of functionality to other objects needed in specific situations.

This is where the difficulties begin. Most articles on the subject give either incorrect examples, or examples that are too artificial, neither of which provide much insight. To begin with, let's separate the two different reasons for using inheritance. One of them is related to the direct purpose of inheritance, the other arises from a misunderstanding of the principles of code organization.

Misuse

A prime example of misuse of inheritance is mixing different levels of abstraction. Above we had an example about users divided by storage type - SQLUser. This causes the following question to arise: how is the user, in terms of our subject area, related to the technical aspects of storing these users? The user isn't related in any way, such code should, as a rule, not exist and inheritance is not intended for it.

Such code appears not from ignorance of OOP, but from misunderstanding of the general principles of code organization, the construction of abstractions. This topic is not specific to OOP, but OOP makes it more difficult because of the large number of new entities it introduces.

The paradox is that the phrase “composition over inheritance” refers precisely to this use of inheritance. In other words, the problem isn't inheritance as such, but that it's turned out to be a convenient way to organize code for those who don't know how to organize it well, and don't know what abstraction barriers and application layers are.

Intended use

The need for class inheritance arises where classes are related by a common code (this is not a subtype relation). In this situation, we need an alternative to inheritance.

The solution to this problem has been known for quite some time, and it's called mixins). Mixins are a real alternative to the proper use of inheritance.


Hexlet Experts

Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>
Suggested learning programs

From a novice to a developer. Get a job or your money back!

Frontend Developer icon
Profession
beginner
Development of front-end components for web applications
start anytime 10 months

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.