4.3 KiB
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:
- 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. - 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. - Decorator: Create abstract decorator classes that also implement the
Component
interface. These classes have a reference to aComponent
object, and they can add, modify, or extend the behavior of the base component. - 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.
- 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.
public interface Text {
String getContent();
}
- Concrete Component: Create a concrete component class
PlainText
that implements theText
interface.
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 theText
interface and has a reference to aText
object.
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
, andUnderlineText
, which extendTextDecorator
and add specific formatting.
public class BoldText extends TextDecorator {
public BoldText(Text decoratedText) {
super(decoratedText);
}
@Override
public String getContent() {
return "<b>" + decoratedText.getContent() + "</b>";
}
}
public class ItalicText extends TextDecorator {
public ItalicText(Text decoratedText) {
super(decoratedText);
}
@Override
public String getContent() {
return "<i>" + decoratedText.getContent() + "</i>";
}
}
public class UnderlineText extends TextDecorator {
public UnderlineText(Text decoratedText) {
super(decoratedText);
}
@Override
public String getContent() {
return "<u>" + decoratedText.getContent() + "</u>";
}
}
- Client Code: In your text editor application, create an instance of the base
PlainText
class and decorate it with one or more formatting decorators.
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.