Este artigo precisa de máis fontes ou referencias que aparezan nunha publicación acreditada que poidan verificar o seu contido, como libros ou outras publicacións especializadas no tema. Por favor, axude mellorando este artigo. (Desde novembro de 2016.) |
Este artigo ou sección precisa dunha revisión do formato que siga o libro de estilo da Galipedia. Pode axudar a mellorar este artigo e outros en condicións semellantes. |
Este artigo ou sección precisa dunha revisión ortográfica e/ou de gramática (recurso útil: corrector ortográfico en liña de galego). Podes axudarte do revisor ortográfico, activándoo en: Preferencias → Trebellos → Navegación → Ortografía: Activar o revisor ortográfico. Colabora connosco neste artigo e noutros en condicións semellantes para que a Galipedia mellore e medre. |
O padrón de deseño Decorador (Decorator) responde á necesidade de engadir de forma dinámica responsabilidades ou funcionalidades a un obxecto. Desta maneira proporciónase unha alternativa flexible á extensión dunha clase. Tamén é coñecido como padrón envoltorio (Wrapper).
Define a interface para os obxectos que poidan ter responsabilidades engadidas.
Define un obxecto sobre o cal se poden engadir responsabilidades.
Implementa a interface da superclase Compoñente delegando no compoñente asociado. Mantén unha referencia ao compoñente asociado.
Engade responsabilidades ao compoñente.
O uso do padrón ten, polo menos, dúas vantaxes:
Co uso de decoradores, pódense engadir e eliminar responsabilidades en tempo de execución. Ademais disto, o uso de herdanza require a creación dunha nova clase para cada responsabilidade adicional. Isto dá lugar a moitas clases, e pode facer necesario o uso de herdanza múltiple (situación que se evita co uso de decoradores).
O decorador ofrece un enfoque para engadir responsabilidades só do que se necesita. En vez de intentar incorporar todas as funcionalidades posibles nunha clase, podemos definir unha clase simple e, a posteriori, ir engadindo funcionalidades de forma incremental con obxectos decorador. Isto trae consigo a vantaxe de non ter que "pagar" por funcións non requiridas, xa que só se engade o que se necesita. Pero tamén ten dous inconvenientes fundamentais:
O decorador compórtase como un envoltorio transparente. Pero desde o punto de vista da identidade de obxectos, estes non son idénticos, polo tanto non deberíamos apoiarnos na identidade cando estamos usando decoradores.
O uso de decoradores dá como resultado sistemas formados por multitude de obxectos pequenos moi parecidos.
public abstract class Compoñente{
abstract public void operacion();
}
public class CompoñenteConcreto extends Compoñente{
public void operacion(){
System.out.println("CompoñenteConcreto.operacion()");
}
}
public abstract class Decorador extends Compoñente{
private Compoñente _compoñente;
public Decorador(Compoñente compoñente){
_compoñente = compoñente;
}
public void operacion(){
_compoñente.operacion();
}
}
public class DecoradorConcretoA extends Decorador{
private String _propiedadeEngadida;
public DecoradorConcretoA(Compoñente compoñente){
super(compoñente);
}
public void operacion(){
super.operacion();
_propiedadeEngadida = "Nova propiedade";
System.out.println("DecoradorConcretoA.operacion()");
}
}
public class DecoradorConcretoB extends Decorador{
public DecoradorConcretoB(Compoñente compoñente){
super(compoñente);
}
public void operacion(){
super.operacion();
comportamentoEngadido();
System.out.println("DecoradorConcretoB.operacion()");
}
public void comportamentoEngadido(){
System.out.println("Comportamiento B engadido");
}
}
public class Cliente{
public static void main(String[] args){
CompoñenteConcreto c = new CompoñenteConcreto();
DecoradorConcretoA d1 = new DecoradorConcretoA(c);
DecoradorConcretoB d2 = new DecoradorConcretoB(d1);
d2.operacion();
}
}
A saída do programa sería a seguinte:
E. Gamma, R. Helm, R. Johnson and J. Vlissides (1994). Design Patterns: elements of reusable object-oriented software. Addison-Wesley.