Decorator Pattern Fundamentals
The Decorator Pattern is a structural design pattern that enables dynamic addition of responsibilities to objects while preserving their original structure. It offers a flexible alternative to inheritance by allowing runtime behavior extension through composition.
Pattern Components
- Component Enterface: Defines the base contract for objects
- Concrete Component: Primary implementation of the component interface
- Decorator Base: Maintains component reference and implements the interface
- Concrete Decorator: Extends functionality without modifying the core interface
Text Processing Implementation Example
interface TextComponent {
void render();
}
class BasicText implements TextComponent {
private String content;
public BasicText(String content) {
this.content = content;
}
@Override
public void render() {
System.out.print(content);
}
}
abstract class TextDecorator implements TextComponent {
protected TextComponent wrapped;
public TextDecorator(TextComponent wrapped) {
this.wrapped = wrapped;
}
@Override
public void render() {
wrapped.render();
}
}
class StyledText extends TextDecorator {
private String style;
public StyledText(TextComponent wrapped, String style) {
super(wrapped);
this.style = style;
}
@Override
public void render() {
System.out.print("<" + style + ">");
super.render();
System.out.print("" + style + ">");
}
}
class CapitalizedText extends TextDecorator {
public CapitalizedText(TextComponent wrapped) {
super(wrapped);
}
@Override
public void render() {
String original = ((BasicText)wrapped).content;
System.out.print(original.toUpperCase());
}
}
Common Implementation Pitfalls
The CapitalizedText decorator contains a critical flaw by assuming the wrapped component is always BasicText. This unsafe casting causes runtime errrors when chaining decorators:
TextComponent text = new BasicText("sample");
TextComponent styled = new StyledText(text, "strong");
TextComponent capitalized = new CapitalizedText(styled); // ClassCastException
Resolution Approach
Maintain consistent interface typing throughout the implementation:
class SafeCapitalizedText extends TextDecorator {
public SafeCapitalizedText(TextComponent wrapped) {
super(wrapped);
}
@Override
public void render() {
// Alternative transformation approach
System.out.print(transformOutput());
}
private String transformOutput() {
// Implement transformation without type assumptions
}
}
AI Code Generation Considerations
When encountering implementation errors in AI-generated code:
- Initiate new sessions with complete code context
- Provide exact compiler error messages
- Specify interface contract requirements clearly
- Verify type consistency across component interactions
Effective Query Strategy
Instead of ambiguous error dsecriptions, provide precise technical context:
Compiler Error:
Incompatible types: StyledText cannot be converted to BasicText