DEV Community

Cover image for Understanding the Decorator Pattern Through a MacBook Customization Example in C#
Ali Shahriari (MasterPars)
Ali Shahriari (MasterPars)

Posted on

Understanding the Decorator Pattern Through a MacBook Customization Example in C#

The Decorator Pattern is a powerful structural design pattern that enables adding new behavior to objects dynamically without modifying their original code. This is especially useful when you want to extend functionalities without creating a complex hierarchy of subclasses.

In this article, I’ll explain the Decorator Pattern using a practical example: customizing a MacBook with different configurations like upgrading RAM, SSD, and adding AppleCare protection.


What is the Decorator Pattern?

The Decorator Pattern allows you to "wrap" an object with additional features or responsibilities at runtime. Instead of creating many subclasses for every possible combination, decorators let you compose behaviors dynamically by stacking objects.


The MacBook Example Overview

We start with a base MacBook configuration:

  • 16GB RAM
  • 256GB SSD
  • Base price
  • Using decorators, we can:
  • Upgrade RAM to 24GB
  • Upgrade SSD to 512GB
  • Add AppleCare protection

Each decorator modifies the price and relevant specs accordingly.


Core Components

The Interface IMacBook
Defines the contract with methods like:

  • GetDescription()
  • GetPrice()
  • GetRamSize()
  • GetSSDSize()

The Base Class BaseMacBook16Ram256SSD

Implements IMacBook and represents the default MacBook configuration.

The Abstract Decorator MackBookDecorator

This class implements IMacBook and wraps another IMacBook instance. It delegates calls to the wrapped instance but can be extended to add or override behavior.

Concrete Decorators

  • MacBookWithAppleCare: Adds AppleCare price and description.
  • MacBook512SSD: Adds extra SSD storage and price.
  • MacBook24RAM: Adds extra RAM and price.

How to Use It

You can compose different MacBook configurations by wrapping the base object with decorators like this:

IMacBook macBook16Ram256SSD = new BaseMacBook16Ram256SSD();
IMacBook macBook16Ram512Sdd = new MacBook512SSD(macBook16Ram256SSD);
IMacBook macBook24Ram512Sdd = new MacBook24RAM(macBook16Ram512Sdd);
IMacBook macBook24Ram512SddWithAppleCare = new MacBookWithAppleCare(macBook24Ram512Sdd);

Console.WriteLine(macBook16Ram256SSD);
Console.WriteLine(macBook16Ram512Sdd);
Console.WriteLine(macBook24Ram512Sdd);
Console.WriteLine(macBook24Ram512SddWithAppleCare);

Enter fullscreen mode Exit fullscreen mode

Each line creates a new configuration by decorating the previous one.


Why Use the Decorator Pattern?

  • Open/Closed Principle: Extend object behavior without changing existing code.
  • Flexibility: Combine decorators in any order to create new behaviors.
  • Avoids Class Explosion: No need to create a subclass for every combination.

Real-World Applications

The Decorator Pattern is widely used in software development:

  • Adding scrollbars or borders in UI frameworks.
  • Enhancing functionalities like logging, caching, or security by wrapping services.
  • Customizing product configurations dynamically, just like our MacBook example.

Conclusion

The Decorator Pattern is an elegant way to add responsibilities to objects dynamically and flexibly. Using this pattern, you keep your codebase maintainable and avoid unnecessary class proliferation.


You can find the full source code for this example on my GitHub repository: DecoratorPattern

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.