--- obj: concept --- # Decorator Pattern ## **Description:** The Decorator Pattern 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. It is used to extend the functionality of classes in a flexible and reusable way, promoting the principle of open-closed design. **How it's Used:** 1. **Component Interface**: Define an abstract class or interface, often called `Component`, that represents the base object's interface. This is the interface that decorators and concrete components will implement. 2. **Concrete Component**: Create a concrete component class that implements the `Component` interface. This class represents the base object to which additional behavior can be added. 3. **Decorator**: Create abstract decorator classes that also implement the `Component` interface. These classes have a reference to a `Component` object, and they can add, modify, or extend the behavior of the base component. 4. **Concrete Decorators**: Create concrete decorator classes that extend the abstract decorator classes. These classes provide specific functionality that can be added to the base component. 5. **Composition**: Use composition to combine the base component with one or more decorators. The decorators can be stacked, allowing multiple responsibilities to be added to the base component in a flexible manner. ## **Example:** Let's say you are building a text editor application, and you want to add text formatting features like bold, italic, and underline. You can use the Decorator Pattern to add these features dynamically to the text without changing the text object itself: - **Component Interface**: Define an interface `Text` that represents the basic text functionality. ```java public interface Text { String getContent(); } ``` - **Concrete Component**: Create a concrete component class `PlainText` that implements the `Text` interface. ```java public class PlainText implements Text { private String content; public PlainText(String content) { this.content = content; } @Override public String getContent() { return content; } } ``` - **Decorator**: Create an abstract decorator class `TextDecorator` that also implements the `Text` interface and has a reference to a `Text` object. ```java public abstract class TextDecorator implements Text { protected Text decoratedText; public TextDecorator(Text decoratedText) { this.decoratedText = decoratedText; } } ``` - **Concrete Decorators**: Create concrete decorator classes for formatting, such as `BoldText`, `ItalicText`, and `UnderlineText`, which extend `TextDecorator` and add specific formatting. ```java public class BoldText extends TextDecorator { public BoldText(Text decoratedText) { super(decoratedText); } @Override public String getContent() { return "" + decoratedText.getContent() + ""; } } public class ItalicText extends TextDecorator { public ItalicText(Text decoratedText) { super(decoratedText); } @Override public String getContent() { return "" + decoratedText.getContent() + ""; } } public class UnderlineText extends TextDecorator { public UnderlineText(Text decoratedText) { super(decoratedText); } @Override public String getContent() { return "" + decoratedText.getContent() + ""; } } ``` - **Client Code**: In your text editor application, create an instance of the base `PlainText` class and decorate it with one or more formatting decorators. ```java public class Client { public static void main(String[] args) { Text text = new PlainText("Hello, world!"); // Decorate the text with formatting text = new BoldText(text); text = new ItalicText(text); text = new UnderlineText(text); // Output the formatted text System.out.println(text.getContent()); } } ``` By using the Decorator Pattern, you can add text formatting features to the base `PlainText` object dynamically. You can easily stack and combine different formatting decorators to achieve various formatting options without modifying the base text object's code. This pattern promotes flexibility and maintainability when extending the functionality of objects.