I Design Pattern: un focus su Decorator
Rientrante in un nuovo tutorial del mese, questo articolo sarà il primo di tanti in cui saranno descritti i principali Design Patterns nell’ambito dell’Ingegneria del Software. Ma, prima di tutto, cosa sono i Design Patterns?
Secondo Wikipedia il Design Pattern in informatica e specialmente nell'ambito dell'ingegneria del software, è un concetto che può essere definito "una soluzione progettuale generale ad un problema ricorrente". Si tratta di una descrizione o modello logico da applicare per la risoluzione di un problema che può presentarsi in diverse situazioni durante le fasi di progettazione e sviluppo del software, ancor prima della definizione dell'algoritmo risolutivo della parte computazionale. È un approccio spesso efficace nel contenere o ridurre il debito tecnico.
I design pattern orientati agli oggetti tipicamente mostrano relazioni ed interazioni tra classi o oggetti, senza specificare le classi applicative finali coinvolte, risiedendo quindi nel dominio dei moduli e delle interconnessioni. Ad un livello più alto, ci sono invece i pattern architetturali che hanno un ambito ben più ampio, descrivendo un pattern complessivo adottato dall'intero sistema, la cui implementazione logica dà vita a un framework.
Il Design Pattern che andremo ad analizzare in questo articolo è quello chiamato Decorator.
IL DESIGN PATTERN DECORATOR
Il Design Pattern Decorator consente all'utente di aggiungere nuove funzionalità a un oggetto esistente senza alterarne la struttura. Questo tipo di modello di progettazione rientra nel modello strutturale, in quanto funge da wrapper per la classe esistente.
Questo modello crea una classe decoratore che avvolge quella originale e fornisce funzionalità aggiuntive mantenendo intatta la firma dei metodi di classe.
Dimostreremo l'uso del Pattern Decorator tramite il seguente esempio in cui decoreremo una forma con un pò di colore senza alterare la classe della forma stessa.
IMPLEMENTAZIONE
Di seguito creeremo un'interfaccia Shape e classi concrete per la sua implementazione. Svilupperemo quindi una classe decoratore astratta ShapeDecorator che implementa l'interfaccia Shape e ha l'oggetto Shape come variabile di istanza.
RedShapeDecorator è una classe concreta che implementa ShapeDecorator.
DecoratorPatternDemo, la nostra classe demo utilizzerà RedShapeDecorator per decorare gli oggetti Shape.
STEP 1
Creiamo l’interfaccia
Shape.java
public interface Shape {
void draw();
}
STEP 2
Creiamo la classe concreta che implementa la stessa interfaccia
Rectangle.java
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Rectangle");
}
}
Circle.java
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("Shape: Circle");
}
}
STEP 3
Creiamo la classe decoratore astratta che implementa l’interfaccia the Shape
ShapeDecorator.java
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape){
this.decoratedShape = decoratedShape;
}
public void draw(){
decoratedShape.draw();
}
}
STEP 4
Creiamo la classe decorator concreta che estende la classe ShapeDecorator.
RedShapeDecorator.java
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape){
System.out.println("Border Color: Red");
}
}
STEP 5
Usiamo la classe RedShapeDecorator per decorare gli oggetti di tipo Shape
DecoratorPatternDemo.java
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle = new Circle();
Shape redCircle = new RedShapeDecorator(new Circle());
Shape redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("Circle with normal border");
circle.draw();
System.out.println("\nCircle of red border");
redCircle.draw();
System.out.println("\nRectangle of red border");
redRectangle.draw();
}
}
STEP 6
Verifichiamo l’output
Circle with normal border
Shape: Circle
Circle of red border
Shape: Circle
Border Color: Red
Rectangle of red border
Shape: Rectangle
Border Color: Red