Decorator.
Clasificación
Estructural.
Intención
Agrega responsabilidad a una clase dinámi-camente. Decorator agrega funcionalidad a una clase de forma flexible.
También conocido como
Wrapper (envoltura).
Motivo
Aplicabilidad
Use decorator:
• Para agregar funcionalidad a un objeto dinámicamente y transparentemente, es-to es, sin afectar a los otros objetos.
• Para manejar responsabilidades que pueden ser eliminadas.
• Para evitar una jerarquía de clases ex-tensa que se hace inmanejable.
Estructura
Participantes
• ConcreteComponent: define los objetos que pueden agregar funcionalidad diná-micamente.
• Decorator: mantiene la referencia a un componente y define una interfaz compatible con component.
• ConcretDecorator: agrega responsabili-dades al componente.
Colaboración
Consecuencias
• Diferentes decoradores pueden ser co-nectados a un mismo objeto.
• Reduce el número de propiedades en las clases de la parte alta de la jerarquía.
• Es simple añadir nuevos decoradores de forma independiente a las clases que ex-tienden.
• Un objeto decorador tiene diferente OID al del objeto que decora.
• Sistemas con muchos y pequeños obje-tos.
Implementación
• Conformidad de interfaces. La interfaz de un objeto decorator debe ajustarse a la interfaz del objeto que decora.
• Omitir la clase abstracta decorator. No hay necesidad de agregar una clase abs-tracta decorator cuando sólo hay que manejar una responsabilidad.
• Mantener los componentes de las clases ligeros. Tanto el componente como los decoradores deben descender de una clase común ligera. Debe ser una interfaz y no un almacén de datos.
• Si la clase componente no es lo suficien-temente ligera es mejor utilizar strategy.
Código ejemplo
//clase que define la interfaz para el componente al
//que se le agrega responsabilidad dinámicamente. (component)
import java.awt.Graphics;
import java.awt.Image;
public interface Dibujo {
public Image getDibujo(Graphics g);
}
//Clase que implementa dibujo (ConcreteComponent)
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class DibujoConcretoA implements Dibujo {
private BufferedImage imagen;
public DibujoConcretoA(){
try{
imagen= ImageIO.read(getClass().getClassLoader().getResource("Dibujo1.jpg"));
}catch (IOException e){
System.out.println("Error al leer la margen");
}
}
public Image getDibujo(Graphics g) {
g.drawString("DibujoConcretoA", 130,130);
return imagen;
}
}
//Clase abstracta que define a las decoraciones (Decorator)
import java.awt.Graphics;
import java.awt.Image;
public abstract class Decorator implements Dibujo {
private Dibujo unDibujo=null;
public Decorator(Dibujo d){
unDibujo= d;
}
public Image getDibujo(Graphics g) {
return unDibujo.getDibujo(g);
}
}
//Decorador que le agrega un marco al dibujo (ConcretDecorator)
import java.awt.Graphics;
import java.awt.Image;
public class AgregarMarco extends Decorator {
public AgregarMarco(Dibujo d) {
super(d);
}
public Image getDibujo(Graphics g){
agregarMarco(g);
return super.getDibujo(g);
}
public void agregarMarco(Graphics g){
g.drawRect(20, 90, 318, 288);
}
}
//decorador que agrega fondo al dibujo (ConcrtetDecorator)
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
public class agregarFondo extends Decorator{
public agregarFondo(Dibujo d) {
super(d);
}
public Image getDibujo(Graphics g){
agregaFondo(g);
return super.getDibujo(g);
}
public void agregaFondo(Graphics g){
g.setColor(new Color(204,203,153));
g.fillRect(20, 90, 320, 290);
g.setColor(Color.BLACK);
}
}
//Cliente que utiliza el dibujo y puede agregar opcionalmente
//decoraciones.
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Image;
import java.awt.Color;
import java.awt.Graphics;
public class Cliente extends JFrame implements ActionListener{
private JPanel panel;
private JButton figura;
private JButton marco;
private JButton fondo;
private JButton todo;
private Image imagen=null;
private Dibujo dibujo= new DibujoConcretoA();
private Dibujo miDibujo=dibujo;
private Decorator d1= null;
private Decorator d2=null;
private Decorator d3=null;
public Cliente(){
panel = new JPanel();
figura= new JButton("Figura");
marco=new JButton("Marco");
fondo= new JButton("Fondo");
todo= new JButton("Todo");
this.setTitle("Dibujo");
this.setSize(360,400);
this.setResizable(false);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel=(JPanel)this.getContentPane();
panel.setLayout(null);
panel.add(figura);
panel.add(marco);
panel.add(fondo);
panel.add(todo);
figura.setBounds(10, 20, 70, 20);
marco.setBounds(100, 20, 70, 20);
fondo.setBounds(190, 20, 70, 20);
todo.setBounds(280, 20, 70, 20);
figura.addActionListener(this);
marco.addActionListener(this);
fondo.addActionListener(this);
todo.addActionListener(this);
d1= new AgregarMarco(dibujo);
d2= new agregarFondo(dibujo);
d3= new agregarFondo(d1);
}
public static void main(String args[]){
new Cliente();
}
public void paint(Graphics g){
g.setColor(Color.white);
g.fillRect(20, 90, 320 ,290);
g.setColor(Color.BLACK);
imagen=miDibujo.getDibujo(g);
g.drawImage(imagen,80,150, 200,200,this);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==figura){
miDibujo=dibujo;
}
if(e.getSource()==marco){
miDibujo=d1;
}
if(e.getSource()==fondo){
miDibujo=d2;
}
if(e.getSource()==todo){
miDibujo=d3;
}
repaint();
}
}
Usos conocidos
• También es usado en los flujos de datos de la entrada y salida, de un lenguaje. Esto es para agregar responsabilidades al flujo, como compresión o conversión a un sistema de caracteres.
Patrones relacionados
• Decorator, puede confundirse como una derivación de un composite con un obje-to complejo, pero decorator agrega fun-cionalidad y su intención no es agregar objetos.
• Decorator permite cambiar la parte exte-rior de un objeto (skin-piel), mientras strategy cambia el mecanismo interno, su comportamiento. Así los dos son patrones que permiten cambiar un bojeto.
Referencias bibliográficas
[1] Erich Gamma et al, Elements of reusable object-oriented software.
[2] Steve Holzner, Design patterns for dummies, Wiley Publishing Inc, Indianapolis, EEUU, 2006, 339.
[3] Jesús García Molina, Análisis y diseño de software - Patrones de diseño, dis.um.es/~jmolina/astema3.
1 comentario:
de favor coloca la imagen q pides en la clase dibujo
Publicar un comentario