Design patterns play a critical role in crafting clean, maintainable, and scalable code. In my previous posts, I’ve covered several key patterns like Factory Method, Builder, Proxy, and Chain of Responsibility. Today, let’s explore another powerful concept: the Composition design pattern.
What is Composition?
Composition is a design principle that favors “has-a” relationships over “is-a” relationships (inheritance). Instead of extending functionality through subclassing, composition achieves it by containing instances of other classes that implement the desired functionality.
There’s a popular saying in object-oriented design: “Favor composition over inheritance.” But why?
Composition vs. Inheritance
Before diving deeper, let’s clarify the difference between these two approaches:
Inheritance: A class extends another class, inheriting its behavior and properties.
Composition: A class contains objects of other classes as members, delegating tasks to those objects.
Consider these key advantages of composition:
- Flexibility: You can change behavior at runtime by swapping component objects
- Reduced coupling: Components are independent and can evolve separately
- No fragile base class problem: Changes to a base class don’t inadvertently affect all subclasses
- Multiple source behaviors: You can incorporate functionality from multiple components, unlike single inheritance
Real-World Problem: Building a Content Management System
Let’s examine a practical scenario: building a flexible Content Management System (CMS) that handles different types of content—articles, videos, podcasts—each with unique features but sharing common operations.
A naive approach might use inheritance:
ContentItem (base class)
↓
├── Article
├── Video
└── Podcast
But what if we need combinations of features? What if some articles have videos? What if we need to add new content types or features without disrupting existing code?
This is where composition shines.
Implementing the CMS with Composition
Let’s build our CMS using composition. First, we’ll define the core interfaces:
Now, let’s implement some concrete content features:
Now, let’s create our base content item class that will use composition:
The class diagram for this implementation would look like:
Using the Composition-Based CMS
Let’s see how we can use our composition-based CMS to create different types of content:
Output is in html format. Below is the visualisation of the output:
Java Composition Pattern
Learn how to use composition in Java
Video Tutorial: Composition in Action
Watch how to implement composition
Advanced Composition Techniques
Mastering composition in large systems

Extending with New Features
One of the key benefits of composition is how easily we can add new functionality. Let’s say we want to add a rating feature to our CMS:
Real-World Application: Enterprise CMS System
In a production environment, this pattern really shines. Let’s look at an enterprise-grade implementation with more sophisticated features.
Creating a premium content
ContentItem premiumTutorial = new ContentItem("Advanced Java Patterns",
"Premium tutorial for design patterns");
premiumTutorial.addFeature(new TextFeature("This premium content covers..."));
premiumTutorial.addFeature(new VideoFeature("https://example.com/premium.mp4", false));
premiumTutorial.addFeature(new AccessControlFeature(AccessControlFeature.AccessLevel.PREMIUM));
premiumTutorial.addFeature(new AnalyticsFeature("premium-tutorial-001"));
Performance Considerations
While composition offers great flexibility, it’s worth noting potential performance impacts:
- Memory Overhead: Each feature is a separate object, which may increase memory usage compared to inheritance-based solutions.
- Delegation Overhead: Method calls must traverse the delegation chain, which can add a small performance cost.
For most applications, these costs are minimal compared to the architectural benefits. However, in performance-critical systems, you might need to balance flexibility with performance needs.
When to Use Composition
Composition is particularly useful when:
- You need to combine behaviors from multiple sources
- You want to change behavior at runtime
- You’re dealing with a complex feature matrix that would be unwieldy with inheritance
- You need to avoid the “fragile base class problem”
Conclusion
Composition offers a powerful, flexible alternative to inheritance-based designs. By focusing on “has-a” relationships rather than “is-a” hierarchies, we can create more adaptable, maintainable systems.
Our CMS example demonstrates how composition allows us to:
- Combine features in creative ways
- Add new functionality without changing existing code
- Create more specialized content types without complex inheritance chains
Next time you’re facing a design challenge that might traditionally call for inheritance, consider whether composition might offer a more flexible solution.
Awesome
Thank you!
Good
Thank you!