A decorator is a structural design pattern that allows behavior to be added to individual objects, either statically or dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is typically used to extend the functionalities of classes in a flexible and reusable way.
The decorator is a well-known design pattern in software engineering. It is one of the patterns described in the “Gang of Four” book, Design Patterns: Elements of Reusable Object-Oriented Software.”
Key Characteristics
-
Composition Over Inheritance: The decorator pattern promotes composition over inheritance by allowing you to wrap objects with additional behavior without modifying their structure.
It helps in adhering to the Single Responsibility Principle by allowing functionality to be divided between classes with unique areas of concern. Flexibility:
Decorators provide a flexible alternative to subclassing for extending functionality. Is a Decorator a Code Pattern? Yes, the decorator is a well-known design pattern in software engineering. It is one of the patterns described in the “Gang of Four” book, “Design Patterns: Elements of Reusable Object-Oriented Software.”
# Base Component
class Coffee
def cost
5
end
def description
"Simple Coffee"
end
end
# Decorator Base Class
class CoffeeDecorator
def initialize(coffee)
@coffee = coffee
end
def cost
@coffee.cost
end
def description
@coffee.description
end
end
# Concrete Decorators
class MilkDecorator < CoffeeDecorator
def cost
@coffee.cost + 2
end
def description
@coffee.description + ", Milk"
end
end
class SugarDecorator < CoffeeDecorator
def cost
@coffee.cost + 1
end
def description
@coffee.description + ", Sugar"
end
end
# Usage
coffee = Coffee.new
puts coffee.description # Output: Simple Coffee
puts coffee.cost # Output: 5
milk_coffee = MilkDecorator.new(coffee)
puts milk_coffee.description # Output: Simple Coffee, Milk
puts milk_coffee.cost # Output: 7
sugar_milk_coffee = SugarDecorator.new(milk_coffee)
puts sugar_milk_coffee.description # Output: Simple Coffee, Milk, Sugar
puts sugar_milk_coffee.cost # Output: 8
Explanation
- Base Component: Coffee class represents the base component with basic functionality.
- Decorator Base Class: CoffeeDecorator class wraps a Coffee object and delegates calls to it.
- Concrete Decorators: MilkDecorator and SugarDecorator classes extend the functionality of the base component by adding their own behavior.
- Usage: The decorators are used to dynamically add behavior to the Coffee object without modifying its structure.
Summary
A decorator is a design pattern that allows you to add behavior to objects dynamically without altering their structure. It promotes composition over inheritance and adheres to the Single Responsibility Principle. The example in Ruby demonstrates how to use decorators to extend the functionality of a Coffee object by adding milk and sugar.