Stal, każdy mniej więcej wie co to za stop – żelaza, węgla i innych pierwiastków. Niby stal to stal, ale każdy stop stali ma inne właściwości i inaczej się zachowuje w zależności od użytych domieszek. Tak samo we wzorcu dekorator, mamy klasę do którego możemy dodawać nowe właściwości lub zachowania, bez modyfikowania jej zawartości. Wszystkie klasy dekoratora implementują ten sam interfejs co dekorowany obiekt.

Dekorator – strukturalny wzorzec projektowy, który ma zalety:

  • Powala na dynamiczne zmiany zachować lub dodawania nowych cech danemu obiektowi
  • Stanowi bardzo poważną konkurencję dla dziedziczenia, wykorzystując kompozycję i dziedziczenie
  • Obiekt dekoratora jest praktycznie całkowicie przeźroczysty dla klienta, który korzysta z niego
  • Implementuje zasadę OOP – otwarte – zamknięte. Klasa implementująca wzorzec dekoratora jest otwarta na rozbudowę poprzez użycie dekoratorów, sama pozostając zamknięta na zmianę kodu
  • Luźna zależność pomiędzy obiektami w systemie

Wady:

  • W przypadku rozbudowanych dekoratorów powstaje dużo małych klas
  • Zbyt pochopne używanie tego wzorca może spowodować dużą złożoność powstającego kodu

Przykładowa implementacja (Java) – klasy implementujące dodawanie formatowania do surowego tekstu:

package pl.shad.net.blog;
 
/**
 * Interfejs wzorca dekorator
 */
interface Decorator{
	String getText();
}
 
/**
 * Główna klasa, która nic nie wie że jest dekorowana
 */
class RawText implements Decorator{
 
	@Override
	public String getText(){
		return "Super duper text ...";
	}
}
 
/**
 * Zmiana formatowania tektu, symulacja konsoli linuxowej
 */
class HtmlFormatText implements Decorator{
	Decorator decoratorObject;
 
	public HtmlFormatText(Decorator decoratorObject){
		this.decoratorObject = decoratorObject;
	}
 
	@Override
	public String getText(){
		return "< div>" + decoratorObject.getText() + "< /div>";
	}
}
 
/**
 * Formatowanie tekstu przy pomocy taga HTML
 */
class ConsoleFormatText implements Decorator{
	Decorator decoratorObject;
 
	public ConsoleFormatText(Decorator decoratorObject){
		this.decoratorObject = decoratorObject;
	}
 
	@Override
	public String getText(){
		return "~linux@login: "+decoratorObject.getText();
	}
}
 
/**
 * Klasa uruchomieniowa
 */
public class DesignPatternsDecorator{
 
	public static void main(String[] args){
		RawText rawText=new RawText();
 
		ConsoleFormatText consoleFormatText=new ConsoleFormatText(rawText);
		HtmlFormatText htmlFormatText=new HtmlFormatText(rawText);
 
		System.out.println("\nRaw text:");
		System.out.println(rawText.getText());
		System.out.println("\nConsole format text:");
		System.out.println(consoleFormatText.getText());
		System.out.println("\nHtml format text:");
		System.out.println(htmlFormatText.getText());
	}
}