void/Readwise/Why Composition Is Often Better Than Inheritance.md
2024-09-14 17:40:32 -03:00

53 lines
5.6 KiB
Markdown

# Why Composition Is Often Better Than Inheritance
![rw-book-cover](https://lh6.googleusercontent.com/proxy/3FDJd1lWoiuZCxfz7C2GRuBjhEQ9Es3OPvuUzs7_qAmYsdPEAiRFKrH9QBOGubPOZOa1I7q6WfEnXHce89uFMceSXhAhs4QbuWmuzw6aeM2G32M3Li8Gr8jwjbSbyaafYID1uQd9hzojASmGiMAp8H1kMjii4g=w1200-h630-p-k-no-nu)
## Metadata
- Author: [[Joost van Dongen]]
- Full Title: Why Composition Is Often Better Than Inheritance
- Category: #articles
- Document Tags: [[dev]] [[dev/design-patterns]]
- URL: https://joostdevblog.blogspot.com/2014/07/why-composition-is-often-better-than.html
- Archive: https://web-archive.alecodes.page/bookmarks?bf=1&search=&title=Why%20Composition%20Is%20Often%20Better%20Than%20Inheritance
> [!note]
> Por lo que entiendo de momento:
> - Usar composition by default unless you have a reason to use inheritance
> - Permite crear código más reutilizable y más _"loosly coupled"_, en donde es más dificil que cambios en una parte del código afecten a otra
> - Composition puede estar relacionado con [[dependency injection]] pero no estoy del todo seguro
> - Razones para usar herencia pueden ser:
> - [[polymorphism]], para crear variantes con una interfaz común
> - Ciertos patrones de diseño como [[factory]] y [[listener]]
> [!tldr]
> The article argues that using composition is often better than inheritance in code structure. While inheritance can seem more natural, composition offers greater flexibility, readability, and reduces the risk of bugs. The author suggests that developers should be cautious with inheritance and consider composition for many situations.
## Highlights
the famous *diamond problem*. What happens when a class A inherits from two classes B and C that both inherit from a single parent D? A now has a D twice and chaos ensues. [View Highlight](https://read.readwise.io/read/01j7k02e4exj8srkx4242fpxkj))
The problem is that when it does, it can often be very difficult to come up with a good solution for how to get rid of it without doing a lot of refactoring. [View Highlight](https://read.readwise.io/read/01j7k01q1m9fafymhnjn692hgk))
Inheritance is very useful for a lot things, for example in polymorphism and in design patters like listeners and factories. [View Highlight](https://read.readwise.io/read/01j7k03r10m6ncdmpn301yc0ns))
An important question in code structure is whether to make classes work together through composition or inheritance. The "has a" relationship versus the "is a" relationship. [View Highlight](https://read.readwise.io/read/01j7jy5adbxd6hqanwamxwyr34))
In my experience intuition often favours inheritance, but it gives so many problems that in many cases composition is better. [View Highlight](https://read.readwise.io/read/01j7jy705wznt9rph7nxb66r4n))
As you can see in this code, CharacterInheritance is shorter. It also feels more natural, since we don't have to write these extra accessor functions for *applyKnockback* and *getPosition*. However, after years of creating both of these kinds of structures I have learned that in a situation like this, using composition is actually more flexible, less sensitive to bugs and even more understandable than using inheritance. [View Highlight](https://read.readwise.io/read/01j7jyaz1nx8p671tzccsgqx29))
Game designers constantly come up with game mechanics that are exceptions to what you already programmed. Saying no to these just because your code structure cannot handle them will seriously damage your game quality [View Highlight](https://read.readwise.io/read/01j7jzcahqza5zye0dxa3yxvdx))
An important goal in game programming is flexibility: making your code in such a way that it is relatively easy to add whatever weird whim the game designers come up with today. In most cases composition is much more flexible than inheritance. [View Highlight](https://read.readwise.io/read/01j7jzdzcr2kv4qtdp378h2chd))
"Readability" is always accomponied by "sensitivity to bugs", since if a programmer does not really understand how something works, then he will likely break it when working on it. [View Highlight](https://read.readwise.io/read/01j7jzem4sqbhqgzj1z7cqm7vx))
*virtual* and *protected* functions. [View Highlight](https://read.readwise.io/read/01j7jzm6wg5dwhd71cmtv7ehzb))
> [!note]
> **Virtual and Protected Functions**: In object-oriented programming, *virtual functions* are member functions in a base class that can be overridden in derived classes. They enable polymorphism, allowing the correct function to be called based on the object's runtime type rather than the type of reference or pointer. This is crucial for implementing dynamic behavior in applications.
> *Protected functions*, on the other hand, are member functions that can be accessed within their own class and by derived classes, but not by outside classes. This access control mechanism helps encapsulate the functionality of a class while still allowing derived classes to utilize or extend that functionality. Together, virtual and protected functions facilitate code reuse and maintainability in complex software systems.
inherited classes work together to create complex behaviour and intertwine more and more over time. [View Highlight](https://read.readwise.io/read/01j7jzh52x8t0pgefbgzdktpay))
this is just too much code to really grasp it all at once without starting to mix things up. The result is that readability decreases and the programmer becomes more likely to introduce bugs because she overlooked something. [View Highlight](https://read.readwise.io/read/01j7jzkaftyev2f34t5x6k5n43))
This keeps the classes from intertwining over time and makes it easier to keep them truly separate. [View Highlight](https://read.readwise.io/read/01j7jzr2x12ncezqhzp3r1qr3h))