👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
Structural Design Pattern - Decorator

Structural Design Pattern - Decorator

Design Pattern

10 Articles

Improve

In this article, let's learn about Decorator Design Pattern in .NET.

Table of Contents

  1. Introduction
  2. Structure
  3. Use Cases
  4. Advantages
  5. Disadvantages
  6. Related Patterns
  7. Summary

Introduction

The decorator pattern is a design pattern that allow dynamically attach additional responsibilities to an object, providing a flexible alternative to subclassing for extending functionality. Also referred to as a wrapper, the decorator pattern allows for the dynamic addition of responsibilities to an object at runtime.

By using the decorator pattern, we can avoid violating Single Responsibility Principle. Our classes would get littered with code that doesn't necessarily belong there. That's where the decorator pattern comes in.

Structure

Component (IRepository):
Defines the interface for objects that can have responsibilities added to them.
Concrete Component (DatabaseRepository):
Defines the logic to read data from database.
Decorator (RepositoryDecoratorBase):
An abstract class implementing the same interface as the component and maintains a reference to a component object. It defines an interface that conforms to the component's interface.
Concrete Decorator (CachedRepositoryDecorator):
Implements the decorator abstract class and adds specific behavior or state to the component.

Code Sample - Code Sample - Decorator Pattern

In the above code, we're implementing the decorator pattern for a repository system. The IRepository interface defines the base functionality with a ReadData method. The DatabaseRepository class is a concrete component that retrieves data from a database. The RepositoryDecoratorBase abstract class acts as the decorator base, maintaining a reference to a repository and delegating the ReadData method. Finally, the CachedDatabaseRepository class is a concrete decorator that extends the behavior by adding caching logic. If a random probability is less than 20%, it returns cached data; otherwise, it delegates to the base repository's ReadData method. This structure allows dynamic composition of repository behaviors, adding features like caching without modifying the core repository code.

Demo Space

Use Cases

  • Dynamic Responsibility Addition - When there's a need to add responsibilities to individual objects dynamically at runtime without affecting other objects.
  • Dynamic Responsibility Removal - When the added responsibilities need to be withdrawn dynamically.
  • Extension by Subclass is Impractical - When extending functionality through subclassing results in an impractical or impossible solution.

Advantages

  • Flexibility - Dynamically add or remove responsibilities at runtime.
  • Single Responsibility Principle - Helps adhere to the single responsibility principle by separating concerns.

Disadvantages

System Litter - This pattern may result in a system with many small, simple classes, potentially increasing the effort required for learning and debugging. Despite these points, the Decorator pattern is a useful starting point because of its simplicity. Finally, let's have a look at related patterns.

  • adapter pattern
  • composite pattern
  • strategy pattern

Summary

In this article we learn't about the decorator pattern that provides a flexible way to extend the functionality of objects dynamically at runtime. It promotes flexibility and adherence to the single responsibility principle, although it may lead to a system with many small classes. Understanding its structure and use cases enables developers to leverage its benefits effectively.

👉🏼 Click here to Join I ❤️ .NET WhatsApp Channel to get 🔔 notified about new articles and other updates.
  • Design Pattern
  • Structural
  • Decorator