Clasificación:
Patrón
Estructural.
Propósito:
Asignar nuevas responsabilidades a un objeto
dinámicamente. Es una alternativa a la creación de subclases por
herencia.
También Conocido como:
Decorator
/ Wrapper.
Intencion:
Agregar
funcionalidad "de adorno" a un objeto.
Motivacion:
Para añadir nuevas responsabilidades a objetos
individuales y no a toda la clase , por ejemplo, una ventana de una
interfaz gráfica puede tener bordes, scrolling, u otros
artifactos. Esto se puede hacer dinámicamente. A veces queremos
añadir responsabilidades a cada uno de los objetos, no a toda una clase.
Una interfaz gráfica de usuario de herramientas, por ejemplo, en caso de que le
permiten añadir propiedades como las fronteras o comportamientos como el
desplazamiento a cualquier interfaz de usuario componente.
Una forma de lograrlo es añadiendo
responsabilidades con la herencia, de una frontera de otra clase
pone un borde alrededor de cada subclase instancia. Esto es
inflexible, sin embargo, debido a la elección de la frontera se hace
estáticamente. Un cliente no puede controlar cómo y cuándo decorar con un
componente de la frontera. Un enfoque más flexible para incluir el
componente en otro objeto que añade la frontera. Adjuntando el objeto se
llama un decorador. El decorador se ajusta a la interfaz del componente
que decora de manera que su presencia es transparente a la del componente
clientes. El decorador remite las solicitudes de los componentes y puede
realizar acciones adicionales (por ejemplo, dibujar una frontera) antes o
después de transmisión.
Aplicabilidad:
Para añadir funciones a los objetos de forma dinámica
y transparente, es decir, sin afectar a otros objetos, esas responsabilidades
puedan ser retiradas en cualquier momento. A veces, un gran número
de independiente de las extensiones son posibles y producen una explosión
de subclases de apoyo a cada combinación. O una definición de la clase
puede ser escondida o de otro modo no disponible para subclassing, para
asignar responsabilidades a objetos individuales de forma dinámica y
transparente, sin afectar a otros objetos
Estructura:
El Decorador envía las peticiones a su objeto
Componente, y puede realizar alguna operación adicional antes o después.
Los
participantes :
• Component:
Define la interfaz que ofrecen
los objetos que poseen responsabilidades añadidas dinámicamente.
•ConcreteComponent:
Define un
objeto al que responsabilidades adicionales pueden serle añadidas.
•Decorator:
Mantiene
referencia a un objeto Component y define una interfaz que conforma
la interfaz del Component.
•ConcreteDecorator:
Añade
las responsabilidades al Component.
Colaboraciones:
Decorator envía las solicitudes a su componente de
objeto. Puede opcionalmente realizar operaciones adicionales antes y
después del envío de la solicitud.
Consecuencias:
Más flexibilidad que la herencia de clases
(estática): El patrón Decorator proporciona una forma más
flexible para añadir funciones a los objetos que puede ser mantenido
con estático (múltiple) de herencia. Con decoradores, las
responsabilidades pueden ser añadir y suprimir en tiempo de ejecución
simplemente conectar y desconectar por ellos. En contrario, la herencia exige
la creación de una nueva clase por cada
responsabilidad (por ejemplo, BordeedScrollableTextView,
BorderedTextView). Esto da lugar a muchas clases y aumenta la complejidad
de un sistema. Además, proporcionando diferentes clases Decorator para
un Componente de clase le permite mezclar y combinar las
responsabilidades.
Permiten añadir una propiedad más de una
vez: Decoradores también hacen más fácil para agregar una propiedad dos
veces. Por ejemplo, para dar TextView una doble frontera, simplemente
conectar dos BorderDecorators. Heredar de una frontera de clase dos veces
es propenso a errores, en el mejor.
Evita cargados clases alto de la
jerarquía: Decorator ofrece un "pay-as-you-go para añadir
responsabilidades. En lugar de tratar de apoyar todas las características
previsibles en un complejo, personalizable clase, puede definir una clase
y añadir funcionalidad incremental con Decorator objetos. Funcionalidad
puede ser simple, compuesto de piezas. También es fácil
de definir nuevos tipos de Decoradores independientemente de las clases de
objetos se extienden, incluso para imprevistos extensiones. La ampliación
de un complejo de clase tiende para exponer los detalles que no estén
relacionados con las responsabilidades que estás agregando.
Un Decorator y su Component no son
idénticos. Desde el punto de vista de la identidad de los objetos,
un DecoratorComponent no es identico al Component. Por esto no
se puede confiar en en la identidad de los objetos cuando se usan Decorators;
dado que el patrón Decorator hace que hayan muchos objetos pequeños que son muy
parecidos.
Implementación:
El siguiente ejemplo permite que un texto
tenga diferentes presentaciones en cuanto a su tipo de fuente, color y tamaño.
package
logicad;
import
java.awt.Color;
import
java.awt.Font;
import
javax.swing.JTextArea;
/**
*
*
@author Katherin
*/
public
abstract class Componente {
protected int aumento = 10;
protected Font fuente;
protected int tipoLetra = Font.ITALIC;
protected Color color;
protected JTextArea pizarra;
public JTextArea getTablero() {
return pizarra;
}
public void setTablero(JTextArea a) {
pizarra = a;
}
public int getSize() {
return aumento;
}
public void setSize(int tam) {
aumento = tam;
}
abstract public void operacion();
}
package
logicad;
/**
*
*
@author Katherin
*/
public
abstract class Decorador extends Componente{
protected Componente componente;
public void setComponente(Componente component) {
this.componente = component;
}
public void operacion() {
if (componente != null) {
componente.operacion();
}
}
}
package
logicad;
import
java.awt.Font;
/**
*
*
@author Katherin
*/
public class
DecoradorConcretoAumento extends Decorador {
public void operacion() {
super.operacion();
AgregarComportamiento();
}
public void AgregarComportamiento() {
aumento=aumento+3;
fuente = new Font("Helvética", Font.ITALIC +
Font.BOLD, aumento);
pizarra.setFont(fuente);
}
}
package
logicad;
import
java.awt.Color;
/**
*
*
@author Katherin
*/
public class
DecoradorConcretoCambioColor extends Decorador {
private int colors;
public void operacion() {
super.operacion();
colors = (int) (Math.random() * 10);
this.AgregarComportamiento();
}
public void AgregarComportamiento() {
switch (colors) {
case 1:
color = Color.BLACK;
break;
case 2:
color = Color.RED;
break;
case 3:
color = Color.BLUE;
break;
case 4:
color = Color.GREEN;
break;
case 5:
color = Color.MAGENTA;
break;
case 6:
color = Color.CYAN;
break;
case 7:
color = Color.DARK_GRAY;
break;
case 8:
color = Color.LIGHT_GRAY;
break;
case 9:
color = Color.ORANGE;
break;
default:
color = Color.PINK;
}
pizarra.setForeground(color);
}
}
package
logicad;
import
java.awt.Font;
/**
*
*
@author Katherin
*/
public class
DecoradorConcretoCursiva extends Decorador {
public void operacion() {
super.operacion();
AgregarComportamiento();
}
public void AgregarComportamiento() {
tipoLetra = (int) (Math.random() * 10);
switch (tipoLetra) {
case 1:
tipoLetra=Font.BOLD;
break;
case 2:
tipoLetra=Font.ITALIC+Font.BOLD;
break;
case 3:
tipoLetra=Font.PLAIN;
break;
case 4:
tipoLetra=Font.ROMAN_BASELINE;
break;
default :
tipoLetra=Font.ITALIC;
}
fuente = new Font("Helvética", tipoLetra,
aumento);
pizarra.setFont(fuente);
}
}
package
logicad;
import
java.awt.Font;
/**
*
*
@author Katherin
*/
public class
DecoradorConcretoReduce extends Decorador {
public void operacion() {
super.operacion();
aumento=aumento-3;
AgregarComportamiento();
}
public void AgregarComportamiento() {
fuente = new Font("Helvética", Font.ITALIC +
Font.BOLD, aumento);
pizarra.setFont(fuente);
}
}
Ahora la
interfaz de la aplicación.
package
interfazd;
import
logicad.Componente;
import
logicad.DecoradorConcretoAumento;
import
logicad.DecoradorConcretoCambioColor;
import
logicad.DecoradorConcretoCursiva;
import
logicad.DecoradorConcretoReduce;
import
java.awt.Font;
import
java.awt.event.ActionEvent;
import
java.awt.event.ActionListener;
import
java.awt.event.WindowAdapter;
import
java.awt.event.WindowEvent;
import
javax.swing.*;
/**
*
*
@author Katherin
*/
public class
Laboratorio extends JFrame implements ActionListener {
private JTextArea tablero;
private String texto = "";
private JButton cambiarColorTexto;
private JButton letraCursiva;
private JButton aumentarSize;
private JButton disminuirSize;
private Componente escrito;
private int tam = 15;
private Font f;
private DecoradorConcretoAumento d1;
private DecoradorConcretoReduce d2;
private DecoradorConcretoCambioColor d3;
private DecoradorConcretoCursiva d4;
public Laboratorio() {
this.setLayout(null);
this.setTitle("Laboratorio de Moléculas");
this.setSize(400, 500);
this.setLocation(100, 100);
f = new Font("Helvetica", Font.ITALIC +
Font.BOLD, tam);
tablero = new JTextArea();
tablero.setSize(350, 300);
tablero.setLocation(10, 10);
tablero.setFont(f);
tablero.setText("");
tablero.setEditable(true);
add(tablero);
JScrollPane areaScrollPane = new JScrollPane(tablero);
areaScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
areaScrollPane.setSize(350, 300);
areaScrollPane.setLocation(10, 10);
this.getContentPane().add(areaScrollPane);
aumentarSize = new JButton();
aumentarSize.setSize(300, 20);
aumentarSize.setLocation(40, 330);
aumentarSize.setText("Aumentar tamaño del
Texto");
aumentarSize.addActionListener(this);
add(aumentarSize);
cambiarColorTexto = new JButton();
cambiarColorTexto.setSize(300, 20);
cambiarColorTexto.setLocation(40, 360);
cambiarColorTexto.setText("Cambiar Color del
Texto");
cambiarColorTexto.addActionListener(this);
add(cambiarColorTexto);
letraCursiva = new JButton();
letraCursiva.setSize(300, 20);
letraCursiva.setLocation(40, 390);
letraCursiva.setText("Letra Cursiva");
letraCursiva.addActionListener(this);
add(letraCursiva);
disminuirSize = new JButton();
disminuirSize.setSize(300, 20);
disminuirSize.setLocation(40, 420);
disminuirSize.setText("Reuducir Tamaño del
Texto");
disminuirSize.addActionListener(this);
add(disminuirSize);
addWindowListener(new Cierre());
}
public void actionPerformed(ActionEvent e) {
texto = tablero.getText();
if (e.getSource() == aumentarSize) {
escrito = new DecoradorConcretoAumento();
}
if (e.getSource() == cambiarColorTexto) {
escrito = new DecoradorConcretoCambioColor();
}
if (e.getSource() == disminuirSize) {
escrito = new DecoradorConcretoReduce();
}
if (e.getSource() == letraCursiva) {
escrito = new DecoradorConcretoCursiva();
}
escrito.setTablero(tablero);
escrito.setSize(tam);
escrito.operacion();
tam = escrito.getSize();
tablero.setText(texto);
tablero = escrito.getTablero();
}
class Cierre extends WindowAdapter {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
}
package
interfazd;
/**
*
*
@author Katherin
*/
public class
Main {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Laboratorio lab=new Laboratorio();
lab.setVisible(true);
}
}
Usos
conocidos:
Muchos
Toolkits de interfaz de usuario orientados a objetos utilizan decorator,
para añadir decoraciones gráficas.
Patrones
Relacionados:
- Decorador vs. Strategy: el Decorador puede actuar antes o después de llamar a los métodos de otro objeto, para cambiar lo que se hace en medio de la llamada a un método se usa el patrón Strategy.
- Es distinto del Adaptador ya que sólo añade responsabilidades a un objeto, no su interfaz.
- Puede verse como un caso degenerado de Composite con un solo componente. Sin embargo, el decorador añade responsabilidades.
Referencias:
PDF-Departamento de Sistemas Informáticos y
Programación Curso de doctorado 1999 - 2000 Patrones de diseño
orientado a objetos.
DesIgn Patterns: Elements of
Reusable Object-Oriented Software Gamma, Helm, Johnson, Vlissides Editorial Addison-Wesley.

mi comentario es simple, despues de analizar y leer detalladamente el blog concluyo diciendo que "no es necesario que reinventemos algo que ya esta creado" si hay software o codigos que han funcionado con exitos en soluciones de problemas similare al mio, solo debo adaptarlo a lo que necesito.....
ResponderEliminarDesde la creacion de la rueda nadie la a reinventado solo el ser humano la a adaptado segun sus necesisades
el patrón fachada se utiliza cuando se necesite proporcionar una interfaz simple para un subsistema complejo, o cuando se quiera estructurar varios subsistemas en capas, ya que las fachadas serían el punto de entrada a cada nivel.
ResponderEliminarPodemos agregar que el patron también conocido como facade es un patrón de software cuyo objetivo se basa en simplificar o hacer más amigable la complejidad asociada a una librería software.
ResponderEliminarQue util es el patron decorador, el poder darle a un objeto responsabilidades siendo manejables a nuestros parametros, evitando crear grandes clases complejas con muchos codigos aunque si se es muy decorado pasamos por tener unas lineas engorrosas y de muy dificil acceso, el uso de este patron es sorprendente utilizados en pequeños programas como en un proyecto de gran envergadura y con faciles codigos
ResponderEliminarLos patrones estructurales de diseño tienen grandes ventaja porque permiten unir sus caracteristicas para mejorar las secuencias y lineas estrategicas que permiten mejorar considerablemente los metodos de desarrollo.
ResponderEliminarlos patrón estructurales de diseño : es la solución más natural a cierto tipode problema común”.Viéndolo de ese modo, parece lógico pensar que cuando nos topemos con uno de esos “problemas modelo” podríamos aplicar “la solución conocida”, sin tener que reinventar la rueda.
ResponderEliminarla Aplicabilidad es un patron muy importante ya que nos permite añadir funciones a los objetos de forma dinámica y transparente, sin la mas minima necesidad de afectar a otros objetos, y aun mas importantes todavia es que esas responsabilidades puedan ser retiradas en cualquier momento
ResponderEliminarEl patron decorator nos permite añadir o eliminar responsabilidades extra a objetos
ResponderEliminarconcretos de manera eficiente y transparente ya que esto se hace sin afectar a
otros objetos, proporcionando una alternativa flexible a la herencia
para extender su funcionalidad; contribuyendo así a reparar inconvenientes frecuentes en el desarrollo de software.
Este comentario ha sido eliminado por el autor.
ResponderEliminarEl Patrón Facade Busca simplificar el sistema, desde el punto de vista del cliente, proporcionando una interfaz unificada para un conjunto de subsistemas, definiendo una interfaz de nivel más alto. Esto hace que el sistema sea. Ronald Vasquez
ResponderEliminarEste comentario ha sido eliminado por el autor.
ResponderEliminarLos patrones de diseño estructural tratan de desacoplar interfaz e implementación de clases y objetos.
ResponderEliminarentre los patrones estructurales, el decorator me parece interesante ya que se aplica para otorgar funcionabilidad a una herencia, subclase de manera rapida y eficaz y asi aplicables todos lo agregados, eliminando la inflexibilidad
ResponderEliminarLos patrones de diseño capturan el conocimiento que tienen los expertos a la hora de diseñar. los patrones ayudan a generar software “maleable”(software que soporta y facilita el cambio, la reutilización ylamejora),los patrones de diseño son guías, no reglas rigurosas.cada patrón describe la solución a problemas que se repiten
ResponderEliminaruna y otra vez en nuestro entorno , de forma que se puede usar esa solución todas las veces que haga falta.
Ambos patrones refieren al diseño estructural de la interfaz o conjunto de interfaces y buscan simplificarlo, haciendo más fácil de usar todas aquellas, minimizando las comunicaciones y dependencias entre el cliente y los subsistemas.
ResponderEliminarLos patrones estructurales son estructural, ya que se puede identificar y clasificar patrones de forma automática, y son muy útiles en la interfaz o todas las interfaces juntas entre usuarios y sistemas, en si va de la mano de las clases y objetos que nos permite añadir o eliminar responsabilidades extra
ResponderEliminar