Quando funcionalidades extras são opcionais, a herança pode gerar uma explosão de subclasses.
O padrão Decorator resolve isso com composição em camadas sem alterar a interface do cliente.
Imagine um sistema de biblioteca que apenas notifica via e-mail.
O que acontece quando queremos adicionar notificações por SMS ou Slack?
interface Notificador { void enviar(String mensagem); } class EmailNotificador implements Notificador { public void enviar(String mensagem) { System.out.println("E-mail enviado: " + mensagem); } }
abstract class NotificadorDecorator implements Notificador { protected Notificador wrappee; public NotificadorDecorator(Notificador wrappee) { this.wrappee = wrappee; } public void enviar(String mensagem) { wrappee.enviar(mensagem); } }
class SmsDecorator extends NotificadorDecorator { public SmsDecorator(Notificador wrappee) { super(wrappee); } public void enviar(String mensagem) { super.enviar(mensagem); System.out.println("SMS enviado: " + mensagem); } }