miércoles, 8 de enero de 2014

PATRON FACHADA (FACADE)



Clasificación:
Patrón Estructural.

Propósito:
Proporcionar una interfaz de alto nivel, unificada a un conjunto de interfaces en un subsistema, haciendo  más fácil de usar todas aquellas, minimizando las  comunicaciones y dependencias entre el liente y los subsistemas.

También conocido como:
Facade.

Intención:
Su objetivo es reducir al mínimo la comunicación y las dependencias entre los subsistemas;  una  manera de lograr este objetivo es introducir un objeto que proporciona la fachada de una sola  interfaz simplificada a la más general de las instalaciones de un subsistema.

Motivación :
Estructurar un sistema en subsistemas ayudando a  reducir la complejidad, estructurando un entorno de programación. 

Aplicabilidad: 
Proporciona una interfaz sencilla a un subsistema complejo, – a medida que un subsistema evoluciona va teniendo más clases, más pequeñas, más flexibles y configurables, – existen clientes que no necesitan tanta flexibilidad y que quieren una visión más simple del subsistema ,– sólo los clientes que necesiten detalles de más bajo nivel accederán a las clases detrás de la fachada, puesto que cuando hay muchas dependencias entre los clientes y las clases de implementación de una abstracción es cuando la fachada desacopla el subsistema de los clientes y de otros subsistemas, mejorando la independencia de subsistemas y la portabilidad.
Para estructurar un sistema en capas –la fachada define el punto de entrada de cada nivel, – se pueden simplificar las dependencias obligando a los subsistemas a comunicarse únicamente a través de sus fachadas.

Estructura :



 Los participantes:
  • Facade: 
 Conoce qué clases son responsables de las peticiones y así, delega las peticiones a los objetos apropiados.
  • Subsystem: 
 Implementa la funcionalidad del subsistema, realiza el trabajo solicitado por el objeto Façade y no  conoce, ni mantiene referencia alguna del objeto mismo Facade. 

Colaboraciones:
Los clientes se comunican con el subsistema haciendo peticiones a la Fachada, que las envía a los objetos del subsistema apropiados (la fachada podría también traducir su interfaz a la de las interfaces del subsistema), de modo que los clientes que usan la fachada no tienen que acceder a los objetos del subsistema directamente. 

Consecuencias:
Oculta a los clientes los componentes del subsistema, reduciendo  el número de objetos con los que tienen que tratar los clientes.
Disminuye el acoplamiento entre un subsistema y sus clientes, un menor acoplamiento facilita el cambio de los componentes del subsistema sin afectar a sus clientes – 
Las fachadas permiten estructurar el sistema en capas, reduciendo las dependencias de compilación. No evita que las aplicaciones puedan usar las clases del subsistema si lo necesitan, eligiendo entre facilidad de uso y generalidad.
El acoplamiento débil permite variar los componentes del subsistema, sin que ello afecte a sus clientes.
La reducción de las dependencias de compilación es de vital importancia en los grandes sistemas de software. 
Una fachada también puede simplificar los sistemas de portar a otras plataformas, ya que es menos probable  que la construcción de un subsistema requiere de la construcción todos los demás. 
Implementación:
package logica;
public class Fachada {
    
    public  String activarAire()
    {
        
        AireAcondicionadoCarro aire = new AireAcondicionadoCarro();
        aire.activarAire();
        return aire.getEstadoAlarma();
    }
    public  String activarLuces()
    {
        LucesCarro luces = new LucesCarro();
        luces.encenderLuces();
        return luces.getEstadoLuces();
    }
    public  String activarAlarma()
    {
        AlarmaCarro alarma = new AlarmaCarro();
        alarma.activarAlarma();
        return alarma.getEstadoAlarma();
    }
}
package logica;
public class AlarmaCarro {
    private String estadoAlarma;
    public void activarAlarma()
    {
        estadoAlarma= "Se ha activado la alarma";
    }
    public void desactivarAlarma()
    {
        estadoAlarma = "Se ha desactivado la alarma";
    }
    public String getEstadoAlarma()
    {
        return estadoAlarma;
    }
package logica;
public class AireAcondicionadoCarro {
    private String estadoAire;
    
    public void activarAire()
    {
        estadoAire = "Aire acondicionado encendido";
    }
    
     public String getEstadoAlarma()
    {
        return estadoAire;
    }
}
package logica;
public class LucesCarro
{
    private String estadoLuces;
    public void encenderLuces()
    { estadoLuces = "Se han encendido las luces";
    }
     public String getEstadoLuces()
    {
        return estadoLuces;
    }
}
package interfaz;
import logica.Fachada;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
public class Conductor extends JFrame implements ActionListener{
    private Fachada facha;
    private Conductor conduc;
    private JButton encenderAire;
 private JButton activarAlarma;
    private JTextArea txtArea;
 public Conductor(){
  this.setSize(400,500);
        this.setLayout(null);
        this.setDefaultCloseOperation(Conductor.DISPOSE_ON_CLOSE);
        this.setTitle(":::Carro:::");
        txtArea = new JTextArea();
        txtArea.setSize(350, 250);
        txtArea.setLocation(10, 10);
        txtArea.setText("");
        txtArea.setEditable(false);
        add(txtArea);
      
  encenderAire = new JButton();
  encenderAire.setSize(150, 50);
  encenderAire.setLocation(50, 300);
  encenderAire.setText("Aire Acondicionado Encendido");
        this.getContentPane().add(encenderAire);
        encenderAire.addActionListener(this);
        activarAlarma = new JButton();
        activarAlarma.setSize(150, 50);
        activarAlarma.setLocation(50, 350);
        activarAlarma.setText("Alarma Encendida");
        this.getContentPane().add(activarAlarma);
        activarAlarma.addActionListener(this);
        addWindowListener(new Cierre());
        facha = new Fachada();
 }
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == encenderAire) {
            txtArea.setText(facha.activarAire());
        }
        if (e.getSource() == activarAlarma)
        {
            txtArea.setText(facha.activarAlarma());
        }
 }
     class Cierre extends WindowAdapter {
        @Override
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    }
}
package interfaz;
/**
 *
 * @author Katherin
 */
public class Main {
    public static void main(String[] args) {
        Conductor ventana=new Conductor();
        ventana.setVisible(true);
    }
}

Usos conocidos:
ObjectWorks \ Smalltalk compilador sistema.  ET en el marco de aplicación + + [WGM88], puede tener una aplicación incorporada en herramientas de navegación para la inspección de sus objetos en tiempo de ejecución. Estas son herramientas de navegación  aplicado en un subsistema que incluye una clase llamada Fachada  "ProgrammingEnvironment". Esta fachada se define como operaciones InspectObject  y InspectClass para acceder a los navegadores.
Las opciones del sistema operativo [CIRM93] utiliza para componer muchas fachadas marcos  en uno. Las principales opciones son abstracciones en procesos, almacenamiento, y la dirección  espacios. Para cada una de estas abstracciones hay un subsistema correspondiente,  aplicarse como un marco, que apoya a las opciones de portar una gran variedad de  plataformas de hardware. Dos de estos subsistemas tienen un "representante" (es decir, la fachada).  Estos representantes son FileSystemInterface (almacenamiento) y de dominio (dirección  espacios). 

Patrones relacionados:
  •  Normalmente sólo hace falta un objeto Fachada, por lo cual suele implementarse como Singleton. 
  • Abstract Factory se puede utilizar con Fachada para proporcionar una interfaz para la creación de  subsistema de objetos en un subsistema de manera independiente. Resumen de fábrica también se puede  utilizarse como una alternativa a la fachada para ocultar las clases específicas de la plataforma.
  • Mediator es similar a la fachada en el sentido de que la funcionalidad de los resúmenes clases. Sin embargo, el propósito del Mediador es arbitraria resumen de comunicación  entre colega objetos, a menudo la centralización de la funcionalidad que no pertenece  en cualquiera de ellos. Un mediador de colegas y son conscientes de comunicarse con  el mediador en lugar de comunicarse unos con otros directamente. En contraste, un  fachada simplemente resúmenes de la interfaz con el subsistema de objetos para que sean más fáciles  a utilizar, pero no definir nuevas funciones, y las clases del subsistema no sabe  sobre él.  
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.

PATRÓN DECORADOR



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.