Skip to content
DevMeme
3987 of 7435
Average inheritance fan vs composition enjoyer - design pattern meme showdown
DesignPatterns Architecture Post #4335, on Apr 20, 2022 in TG

Average inheritance fan vs composition enjoyer - design pattern meme showdown

Why is this DesignPatterns Architecture meme funny?

Level 1: Hand-Me-Down vs Custom Fit

Imagine you have two kids building things. One kid gets a toy castle handed down from his older brother. It’s already built, and he can play with it, maybe change the flags on top, but the structure is fixed. Sometimes it feels awkward because it wasn’t made for him – parts of it don’t quite fit what he wanted. This is like inheritance in programming: you’re using something pre-made (from a parent) and just doing small tweaks.

Now the other kid has a box of LEGO bricks and builds his own castle from scratch. He picks each piece and puts it together just the way he likes. He can make the castle tall or short, add three towers or one, build a moat or redesign the gate – it’s fully up to him. This is like composition: mixing and matching pieces to get exactly what you need. In the end, the kid with the LEGO castle is super proud and happy with what he built, because it’s custom-fit to his idea. He’s standing there smiling confidently, like “Yep, I made this and it’s just right.” Meanwhile, the kid with the hand-me-down castle might be a bit less excited – he got something that works but it’s a bit clunky and not really his.

In the meme, the left side “inheritance fan” is like the kid stuck with the hand-me-down toy: he’s not looking too thrilled (maybe even a little frustrated). The right side “composition enjoyer” is like the kid who built his own awesome toy: he’s posing like a rockstar, feeling cool because everything fits perfectly. The joke is saying that building things piece by piece (choosing your own parts) ends up much better than just inheriting whatever someone else made. Even if you’re not a programmer, you can feel why the right side is happier – who wouldn’t be more confident wearing an outfit or playing with a gadget they put together exactly how they wanted, versus one that’s a leftover? The meme uses this simple idea to get a laugh out of developers, because it reminds them of that moment they stopped using only hand-me-down solutions and started assembling their own best solutions. It’s basically showing that making your own custom fit design (in code or in anything) feels great – no wonder the guy on the right is smiling!

Level 2: Composition Over Inheritance

At its core, this meme is teaching a common programming lesson: favor composition over inheritance. If you’re a newer developer, let’s break down what that means. In Object-OrientedProgramming (OOP), we use classes and objects to model things in code. Two key ways to reuse code in OOP are called inheritance and composition. This meme humorously compares them, treating inheritance as the over-hyped approach and composition as the cooler alternative.

  • Class inheritance is when one class is defined as a specialized version of another. This creates a parent-child relationship between classes. The child class (subclass) automatically gets the variables and methods of the parent class (superclass). We often describe this as an “is-a” relationship. For example, imagine a base class Animal with a method makeSound(). If you create class Dog extends Animal, you’re saying "a Dog is an Animal." Dog will inherit makeSound() (maybe defined to bark), along with any other behaviors or data Animal has. Inheritance is taught early because it reduces duplicate code – you write common stuff in Animal once, and Dog, Cat, Elephant subclasses all reuse it.

  • Struct composition (or just composition) is a different approach where instead of class relationships, you build classes out of other classes. Composition is described as a “has-a” relationship. For example, a Car has an Engine rather than thinking of a Car as a kind of Engine. In practice, this means the Car class might have a field that is an Engine object. The Car doesn’t inherit methods from Engine; it just uses the Engine’s functionality by calling its methods. You can do this with any objects: compose a complex object from simpler parts. You might have a Computer class that has a CPU object, a Memory object, etc. – it’s like plugging components together.

Let’s compare these with a simple code-style illustration:

// Inheritance example:
class Engine {
    public void start() { /* ... */ }
}
class Car extends Engine {  // Car is mistakenly made a subclass of Engine
    public void drive() { /* ... */ }
}
// This is actually bad design: A Car is NOT a type of Engine!

In the above pseudo-code, someone made Car inherit from Engine just to reuse the start() method. That doesn’t logically model reality (a car isn’t an engine). It’s an overuse of inheritance for code reuse.

// Composition example:
class Engine {
    public void start() { /* ... */ }
}
class Car {
    private Engine engine;  // Car has an Engine
    public Car(Engine engine) {
        this.engine = engine;
    }
    public void drive() { 
        engine.start();
        /* ... driving ... */ 
    }
}
// This is good design: Car has an Engine, using composition.

Here, Car contains an Engine instance instead of extending Engine. The Car class can use engine.start() whenever it needs to, but Car and Engine remain separate concepts. This is composition in action. If later we want a Car with a different kind of engine (say an ElectricEngine vs GasEngine), we can just create different Engine subclasses or implementations and plug them in without touching the Car code. With inheritance-only design, you might have been tempted to do ElectricCar extends Car and GasCar extends Car to handle differences, leading to multiple car classes. Composition sidesteps that explosion of subclasses by configuring objects with different parts.

Now, why does the meme portray CompositionOverInheritance as the superior, more “enjoyable” method? Because experienced developers have learned that while inheritance can simplify small examples, it can cause problems as codebases grow. One big issue is tight coupling: inheritance ties the child class to details of the parent class’s implementation. If the parent class changes, the child can break unexpectedly. Another issue is that class hierarchies can become rigid – it’s hard to adapt them to new requirements without modifying a bunch of classes. For instance, if you built a game with an Enemy base class and dozens of subclasses for each enemy type, but later you need a new kind of enemy that doesn’t fit neatly into the existing hierarchy, you’re in a tough spot. You might end up forcing it into a subclass that doesn’t really make sense or refactoring a lot of code.

Composition, on the other hand, tends to keep things modular. Each class or struct has its own small job, and they communicate or collaborate through well-defined interfaces. If you need something new, you can often achieve it by composing objects in a new way, rather than touching a bunch of existing inheritance code. For example, if our game’s enemies were built by composition, you might have an Enemy class that has a behavior object (for how it attacks). To create a new enemy type with a new attack style, you could just write a new behavior class and give it to an Enemy instance, rather than subclassing Enemy yet again. This is much cleaner and only affects the new code you write.

The meme’s format labels one side an "Average ... Fan" and the other an "Average ... Enjoyer". This format is a popular internet joke. Here it suggests: an average inheritance fan might be a less experienced programmer who thinks using a deep class hierarchy is the coolest or only way to design things. The average composition enjoyer is the seasoned programmer who has discovered a better way and is quietly confident about it. The left image (inheritance fan) looks a bit chaotic – it’s actually a known meme image of a guy looking unsophisticated or overly excited in a low-quality photo. This represents someone enthusiastically using inheritance everywhere (“Look, I made everything a subclass, so OO!”) without realizing the downsides. The right image (composition enjoyer) is a handsome, confident man in good lighting – a meme representation of the Chad or gigachad (slang for someone at peak coolness). This implies that using composition makes your design cleaner, more robust, and generally cooler in the programming world.

Let’s connect this to DesignPatterns_Architecture: The famous Gang of Four design patterns book from 1994 explicitly advises to use composition rather than inheritance when possible. Many of the design patterns (like Decorator, Strategy, Adapter, etc.) show how to compose objects to extend behavior, instead of relying on subclassing. Why? Because it’s easier to manage and test small, composable pieces. This principle is hammered into seasoned devs so much that "favor composition over inheritance" becomes almost a mantra. It’s also a matter of CodeQuality and maintainability – code built with composition usually has classes that are easier to reuse in different contexts and less entangled.

To put it simply: inheritance is like getting a pre-made structure and tweaking it, whereas composition is like building with LEGO blocks – you combine pieces to get exactly what you need. The meme is saying that the LEGO approach (composition) results in a design that is elegant and strong (hence the suave enjoyer), while the overuse of inheritance can leave you with something brittle or mismatched (hence the awkward fan). Developers find this funny because the contrast is so relatable: almost every programmer goes through a phase of overusing inheritance (because that’s what initial OOP lessons emphasize), followed by the "aha!" moment when they realize composition often leads to simpler, more adaptable code. The meme just personifies that journey, with the composition guy clearly winning the design choice meme battle. In the end, the advice is clear: when designing your code, if you have a choice, try using composition to assemble what you need, and use inheritance more sparingly. Your future self (and any fellow developers working with your code) will likely be as grateful — and as happy as the enjoyer on the right panel!

Level 3: Is-A vs Has-A Showdown

This meme throws down a gauntlet in the long-running inheritance vs composition debate of Object-Oriented Programming (OOP) design. On the left, we have the "Average CLASS INHERITANCE Fan" – depicted by a blurry, unimpressive figure. On the right, the "Average STRUCT COMPOSITION Enjoyer" – a sharply dressed, confident individual. This contrast humorously implies that programmers who cling to class inheritance are the naive "fans," while those who embrace struct composition are the enlightened "enjoyers." It’s a satirical take on the famous OOP principle “favor composition over inheritance.” Seasoned developers often smirk at this because they've lived through the pain of deep class hierarchies and found salvation in simpler composition-based designs.

In classic OOP, using class inheritance means you define a new class by extending an existing one. The subclass automatically inherits fields and methods of the parent class and can override some of them. It’s a quick way to reuse code. An early-career inheritance fan might eagerly build tall class trees: e.g., a generic Vehicle class, then Car extends Vehicle, then ElectricCar extends Car, and so on. At first glance, this is-a relationship (ElectricCar is a Car is a Vehicle) feels elegant. But as systems grow, big inheritance hierarchies become a source of headaches. Subclasses are tightly coupled to their base classes – any change in the parent can ripple through all children (often called the fragile base class problem). Maintenance gets tricky: imagine needing to alter a fundamental behavior in Vehicle – suddenly 15 different subclasses might break or exhibit weird bugs. 🥴 Over time, rigid hierarchies can turn into a yo-yo problem, where a developer reading code must bounce up and down through class definitions to understand what’s happening. The left side of the meme (the inheritance "fan") represents this overzealous use of inheritance that many of us did early on, only to regret later.

Another pitfall is violating the Liskov Substitution Principle (LSP), a core rule in OOP that says a subclass should be usable wherever its parent class is expected, without surprising results. Inheritance fans sometimes subclass inappropriately and break this rule. The classic example: making a Square subclass of Rectangle. Yes, mathematically a square is a rectangle, but if your Rectangle class has methods like setWidth and setHeight, a Square that overrides these to keep sides equal will behave oddly when used through a Rectangle reference. For instance:

Rectangle r = new Square();
r.setWidth(5);
r.setHeight(10);
System.out.println(r.getArea());  // Is it 50 or 100? Surprise!

Code expecting any Rectangle might be baffled that our Square subclass doesn’t act like a normal rectangle (width vs height confusion). This kind of LSP violation is a known anti-pattern caused by forcing an is-a relationship where it doesn’t perfectly fit. Seasoned devs have learned the hard way that inheritance can backfire unless the real-world relationship is truly and always an “is-a.”

Struct composition, by contrast, is all about the has-a relationship: instead of class Car extending class Engine (which makes no sense – a Car isn’t a type of Engine), a Car simply has an Engine as a component. Composition means building complex behavior by combining simpler, self-contained pieces. The term "struct composition" here hints at using plain structs or simple classes as building blocks. For example, in C or Go you might literally put one struct inside another. In higher-level OOP languages (Java, C#, Python), composition just means a class contains references to other class instances, rather than inheriting from them. The right side of the meme – the composition enjoyer – is basically the Chad of software design patterns, confidently using simpler objects and aggregation to get the job done. This approach leads to code that’s easier to change and less tightly bound to a rigid hierarchy.

Why do experienced engineers enjoy composition so much? Because it yields more flexible and maintainable designs. With composition, you can swap out parts or modify behavior without tearing down an entire inheritance tree. Need a Car to have a different engine behavior? Give it a different Engine object or perhaps a strategy object defining how the car moves – no subclass explosion required. In fact, many classic design patterns (Strategy, Decorator, Adapter, etc.) prefer composition. For example, the Strategy Pattern might have a Bird class hold a FlyBehavior interface reference. A penguin and an eagle are both Bird instances, but the penguin’s FlyBehavior is a “no-fly” implementation, while the eagle’s is a “fly-high” implementation. We didn’t need Penguin extends Bird and override a bunch of methods – we just gave one bird a different component. Decorator Pattern is another: instead of subclassing a UI widget 5 times to add features, you wrap the widget in decorator objects (each adds one feature) – that’s composition in action. These patterns are praised in the famous Design Patterns (Gang of Four) book, which bluntly states: “Favor object composition over class inheritance.” It’s basically the enjoyer’s motto!

From an architecture and CodeQuality standpoint, composition keeps codebase modules loosely connected (low coupling, high cohesion). Each class or struct has a single focused job (Single Responsibility Principle, anyone? 😀). Changes remain localized. If you want to improve the braking system of a car in a composition design, you might swap out the Brakes object for a better one. In an inheritance design, you might have to create a SportsCar subclass with modified braking, or, worse, edit the base Car and risk every vehicle type’s behavior. With composition, you often get cleaner unit tests too – you can inject a dummy component into your object for testing. For example, test a Car by giving it a fake Engine object that simulates failures, without having to subclass or monkey-patch anything. Experienced devs love this flexibility; it prevents the dreaded domino effect where one fix breaks half the subclasses in the hierarchy.

The meme’s humor also lies in its use of the "Average Fan vs Enjoyer" format. This format exaggerates a comparison: the left side (inheritance) is portrayed as the goofy or unimpressive choice, and the right side (composition) as the cool, superior choice. In the image, the inheritance fan looks like a grainy webcam shot of someone screaming – not exactly a picture of success. 😂 Meanwhile, the composition enjoyer is basically the GigaChad of programming design: impeccably lit, stylish, a smug look of “I know I made the right choice.” This visual gag resonates with developers who have lived through the evolution of thinking: many of us started as inheritance-happy fans in university or our first jobs (making class hierarchies for every little thing because that’s what our textbooks did). Later on, after wrestling with unmanageable inheritance chains and nasty bugs, we became composition enjoyers, confidently using CompositionOverInheritance in our designs. The right panel’s confident aura is how you feel when you refactor a cluttered class hierarchy into clean, composable pieces and everything just clicks into place.

It’s worth noting that the meme paints with a broad brush – class inheritance isn’t universally evil. There are valid uses for inheritance (for example, when you have a clear-cut hierarchy that won’t change, or when using a framework that requires subclassing of its components). But the joke here is highlighting a real industry trend: as a rule of thumb, modern software design prefers simple composition of objects to deep inheritance trees. The DesignPatterns_Architecture mindset today is to use inheritance sparingly, and only when it truly models an is-a and passes the LSP smell test. Otherwise, composition gives you less trouble down the road.

In summary, the meme is a tongue-in-cheek design pattern showdown. The InheritanceVsComposition battle has a clear winner in the court of developer opinion: the suave composition enjoyer triumphs over the overeager inheritance fan. Seasoned devs are effectively saying, “Been there, done that with inheritance. Composition is just so much cleaner and calmer.” No wonder the enjoyer on the right is beaming with pride – his code is likely easier to reason about and adapt, which in developer land is a true mark of quality. He’s the embodiment of that hard-won wisdom: compose your code like a fine-tuned machine, rather than nesting it in an obtuse class family tree. 😎

Description

Two-panel "Average X Fan / Enjoyer" meme split by a vertical black line. Left panel text (top to bottom): "Average", large bold white text with black outline "CLASS INHERITANCE", then "Fan". Behind the words is a blurry, muted-color screenshot of a person in poor lighting, evoking an unimpressive vibe. Right panel text (top to bottom): "Average", large bold white text "STRUCT COMPOSITION", then "Enjoyer". The background shows a sharply dressed, well-lit person posing confidently. The joke contrasts object-oriented class inheritance with composition, implying seasoned engineers prefer composition for cleaner, more maintainable designs. It riffs on long-running OOP debates about tight coupling, substitution pitfalls, and the "composition over inheritance" principle familiar to senior developers

Comments

7
Anonymous ★ Top Pick Nothing says “enterprise-grade polymorphism” like spinning up a war room to re-prove Liskov after every refactor - meanwhile the composition guy just swaps a struct and heads to lunch
  1. Anonymous ★ Top Pick

    Nothing says “enterprise-grade polymorphism” like spinning up a war room to re-prove Liskov after every refactor - meanwhile the composition guy just swaps a struct and heads to lunch

  2. Anonymous

    The inheritance fan explaining why their 37-level hierarchy makes perfect sense while the composition enjoyer just ships working code and goes home at 5

  3. Anonymous

    Inheritance gives you a banana, the gorilla holding it, and the entire jungle; composition lets you order just the banana - with dependency injection as the delivery fee

  4. Anonymous

    The real irony? Both camps will spend 3 hours in code review debating this, then ship a monolithic God class that does everything anyway because 'we need to meet the sprint deadline.' At least the composition enjoyer can claim they were *thinking* about SOLID principles while violating every single one

  5. Anonymous

    Inheritance: one hotfix triggers a seven-level virtual-dispatch at 2am; composition: small structs with clear interfaces, and the compiler takes your pager

  6. Anonymous

    Inheritance: inheriting your parents' baggage. Composition: assembling only the parts you actually need

  7. Anonymous

    Inheritance: tweak BaseClass at 5pm and wake up PagerDuty; composition: swap a struct field and let the compiler yell in CI instead of customers in prod

Use J and K for navigation