Implementing Runtime Behavior Augmentation with the Decorator Pattern in Java
The Decorator Pattern enables the dynamic addition of new features to existing objects without modifying their underlying structure. Classified as a structural design pattern, it functions by wrapping an object within another class that acts as a proxy or container.
This approach creates a decorator class that encapsulates the target component. It extends functionality while preserving the original class's interface and method signatures. The following implementation demonstrates adding visual styling effects to geometric shapes with out altering the core shape definitions.
Step-by-Step Implementation
1. Define the Component Interface First, establish a common interface representing the base component. Renderable.java
public interface Renderable {
void show();
}
2. Create Concrete Components
Develop specific classes that implement the Renderable interface directly.
SolidCircle.java
public class SolidCircle implements Renderable {
@Override
public void show() {
System.out.println("Geometry: Circle");
}
}
SolidRect.java
public class SolidRect implements Renderable {
@Override
public void show() {
System.out.println("Geometry: Rect");
}
}
3. Establish Abstract Wrapper
Construct an abstract class that implements the Renderable interface and holds a reference to a Renderable instance for delegation purposes.
VisualWrap.java
public abstract class VisualWrap implements Renderable {
protected Renderable innerTarget;
public VisualWrap(Renderable innerTarget){
this.innerTarget = innerTarget;
}
public void show(){
innerTarget.show();
}
}
4. Develop Concrete Wrappers Inherit from the abstract wraper to add specific enhancements. This example adds a colored frame effect. FrameWrapper.java
public class FrameWrapper extends VisualWrap {
public FrameWrapper(Renderable innerTarget) {
super(innerTarget);
}
@Override
public void show() {
innerTarget.show();
applyBorderEffect();
}
private void applyBorderEffect(){
System.out.println("Style: Red Frame");
}
}
5. Execute Client Logic The client constructs objects by injecting concrete components into wrappers to modify behavior at runtime. AppInit.java
public class AppInit {
public static void main(String[] args) {
Renderable basicCircle = new SolidCircle();
Renderable styledCircle = new FrameWrapper(new SolidCircle());
Renderable styledRect = new FrameWrapper(new SolidRect());
System.out.println("Standard Geometry Output");
basicCircle.show();
System.out.println("\nGeometry with Added Style");
styledCircle.show();
System.out.println("\nRect with Added Style");
styledRect.show();
}
}
6. Expected Execution Result Running the application produces the following output, confirming that the decorasion is applied on top of the original object:
Standard Geometry Output
Geometry: Circle
Geometry with Added Style
Geometry: Circle
Style: Red Frame
Rect with Added Style
Geometry: Rect
Style: Red Frame