Patrón Singleton
Este patrón se ve asociado a la palabra único, ya que este du diseño así lo amerita, una única instancia de un objeto. Algunas de las propiedas de este patrón:
• Garantiza que una clase sólo tenga una instancia.
• Proporciona un punto de acceso global a dicha instancia.
• Trabaja mediante un método especial que se utiliza para instanciar el objeto.
Cuando el método es llamado, revisa si ya existe otro objeto instanciado. Si ya existe, retorna una referencia al objeto, sino, el método crea la instancia y retorna la referencia a esa nueva instancia. Es decir:
• En esencia, la idea es que cada objeto en la aplicación use la misma instancia de Singleton.
• Esto evita tener que pasar la instancia a todos los objetos que quieran utilizarla.
• El patrón Singleton hace a los objetos responsables de sí mismos.
Ejemplo
Supones que hay una aplicación que simula a tres estudiantes pintan sobre un mismo lienzo, cada uno de los estudiantes harian un total de tres instancias (new Estudiante()) y una única instancia de lienzo (new Lienzo()). Por qué una instancia de lienzo y no tres? porque los tres estudiantes deben compartir el mismo lienzo, es decir, los tres pintan el mismo lienzo al mismo, eso si, puede ser que los tres pinten el lienzo al mismo tiempo, o que cada uno pinte cuando quiera.
Según la descripción de la aplicación prodríamos hacer la instancia de un lienzo y darle ese mismo lienzo a los tres estudiantes, eso sería lo común suponiendo que la clase Lienzo tiene color y la clase Estudiante tiene carnet.
Lienzo lienzo = new Lienzo("blanco");
Estudiante est_1 = new Estudiante(001, lienzo);
Estudiante est_2 = new Estudiante(002, lienzo);
Estudiante est_3 = new Estudiante(003, lienzo);
est_1.pintar("verde");
est_1.pintar("azul");
est_1.pintar("rojo");
El código anterio está implementado de la forma “convencional”, pero esto tiene sus consecuencias, ya que el objeto Lienzo puede ser altera con libertad y claro está que nadie tiene control sobre ese objeto, es decir, cualquier puede darle al objeto Lienzo el valor y las cantidad de instancias sin llevar un control del mismo. Para evitar esto, se aplica el patron Singleton:
public class Lienzo(){
public Static Lienzo LIENZO_COMPARTIDO = null;
private String color;
private Lienzo(){
this.color = "blanco";
}
public synchronize static Lienzo getInstancia(){
if (LIENZO_COMPARTIDO == null) LIENZO_COMPARTIDO = new Lienzo();
return LIENZO_COMPARTIDO;
}
public void pintar(String color){
this.color = color;
}
}
La variable public <strong>LIENZO_COMPARTIDO</strong> va a ser la que permita el la interacción entre las las demas clases de la aplicación y la instancia de el Lienzo, hay que destacar que el constructor se declara privado, asi se evita instancias descontroladas del Lienzo.
El método <strong>public synchronize static Lienzo getInstancia()</strong> es el encargado de dar la única instancia del Lienzo, éste verifica si ya hay una instancia creada y si ya la hay entonces la retorna, manteniendo asi una única declaración.
Reconstruyendo el primer código de ejemplo, junto con el anterior, quedaría:
Estudiante est_1 = new Estudiante(001);
Estudiante est_2 = new Estudiante(002);
Estudiante est_3 = new Estudiante(003);
est_1.pintar("verde");
est_1.pintar("azul");
est_1.pintar("rojo");
//metodo pintar de la clase Estudiante
public void pintar(String color){
Lienzo.gertInstancia().pintar(color);
}
Ya los estudiantes de igual forma pueden pintar el lienzo sin necesidad de tener el mismo lienzo cada uno de ellos, es en el metodo pintar de la clase Estudiante donde se nota el comportamiento del patron Singleton.
Read MorePatrón Composite
El patrón composite es un patrón de diseño muy poderoso en si mismo, consiste en crear objetos a partir de otros mas pequeños, tambien puede contener objetos que tienen otros objetos, dando el aspecto de un arbol eneario.
En otras palabras, lo que afecte al objeto de mayor jerarquia alterará a todos sus objetos “hijos”, entonces, supongamos que crearemos un aplicacion que contiene etiquetas y tambien paneles, ambos son componentes, que quiere decir esto? pues que tanto etiqueta como panel estan implementan una interfaz comun, por lo tanto va a tener las mismas funciones, y esto para que sirve? el panel a diferencia de una etiqueta, tiene la posibilidad de almacenar dentro de el otros componentes (mas etiquetas o mas paneles), entonces si queremos pintar todos los componentes de color rojo lo normal seria ir uno a uno pintandolo de color rojo (etiquetas y paneles), pero con el patron composite nos evitamos esta tarea, y con una simple llamada al metodo pintar del componente de mayor jerarquia se pintan todos los demas componente debajo de él, vemos:
Interfaz Componente:
La siguiente interface sera la encargada de establecer el objeto con el cual vamos a trabajar. Todas aquellas clases que implementen esta interfase, tendran como obligacion -pintar- ya se de una forma u otra.
public interface Componente {
/**
* El componente se pintara de alguna forma dependiendo de la clase que la
* implemente. El color a pintar el componente sera el parametro que recibe
* el metodo
*/
public void pintar(String color);
}
La Clase etiqueta:
La clase Etiqueta pasa a ser un componente ya que esta implementado la interfaz Componente. Hay que recordar que esta clase por obligacion debe de “pintar” de alguna forma este componente
public class Etiqueta implements Componente{
/**
* vamos a usar el atributo nombre para identificar el componente con el
* cual estamos trabajado
*/
private String nombre;
public Etiqueta(String nombre) {
this.nombre = nombre;
}
/**
* Implementamos el metodo pintar de la interfase Componente.
* El metodo nos indica simplemente que este componente se pinto con el
* color que se nos indico, el mensaje es para asegurar esa accion
*/
public void pintar(String color)
{
System.out.println("Se pinto a " + nombre + " de color " + color);
}
La Clase Contenedor (Panel):
Esta clase a diferencia de la clase Etiqueta posee una lista de componentes que estan por debajo de su jerarquia, haciendo de este componente la forma de un arbol. La clase Etiqueta no puede contener a ningun componente, mientras que esta clase puede poseer todos los que sean y puede poseer aun otros contenedores
public class Contenedor implements Componente {
/**
* vamos a usar el atributo nombre para identificar el componente con el
* cual estamos trabajado
*/
private String nombre;
/**
* A diferencia de la clase etiqueta aca vamos a tener una estrutura de
* almacenamiento para "almacenar" todos aquellos componentes (ya sean
* contenedores o etiquetas). Asi como en un explorador, carpetas pueden
* tener carpetas y otras carpertas mas carpetas, dando asi la forma de un
* arbol. En este caso la clase Contenedor seria una carpeta y la clase
* Etiqueta seria algo asi como un archivo de texto. La capeta puede tener
* adentro mas carpetas y archivos de texto, mientras que los archivos de
* texto no pueden contener a nadie
*
*/
private ArrayList <componente> componentes;
public Contenedor(String nombre) {
setNombre(nombre);
setComponentes(new ArrayList());
}
public Contenedor() {
setNombre("");
setComponentes(new ArrayList());
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
/**
* Implementamos el metodo pintar de la interfase Componente.
* El metodo nos indica simplemente que este componente se pinto con el
* color que se nos indico, el mensaje es para asegurar esa accion, ademas,
* se van pintando todos los demas componentes (ya sean contenedores o
* etiquetas), solo se hace una llamada del metodo pintar de cada componente
* Es caca donde esta la magia del Patron Composite, ya que resuleve de una
* forma muy sencilla la mara de pintar todos los componentes comprendidos
* dentro de un contenedor. Muchas veces queremos alterar objetos que estan
* contenidos dentro deotrs mas grandes, con este patron se pretende alterar
* cada uno de estos objetos tan solo alterando el mas grande o el de mayor
* jerarquia.
*/
public void pintar(String color) {
for (Componente c : componentes) c.pintar(color);
System.out.println("Se pinto a " + nombre + " de color " + color);
}
/**
* Aca vamos ir agregando todo los componentes necesarios al contenedor, ya
* sean mas contenedores o mas etiquetas. Hay que tomar en cuenta que aca es
* donde se puede notar una estructura de arbol, porque puede ser que
* vayamos a agragrgar un contenedor con componetes adentro, por ejemplo:
*
* -contenedor1
* -etiq1
* -etiq2
* -contenedor2
* -etiq4
* -etiq5
* -etiq3
* ...
*
* Aca podemos observar que si agregamos el contenedor2 y luego llamamos al
* metodo pintar de esta clase se pintara tanto el contenedor2 como sus
* componentes internos, que en este caso seria etiq4 y etiq5
*
*/
public void add(Componente c)
{
getComponentes().add(c);
}</componente>
Ahora hagamos un main para ilustrar el codigo:
public class TestComponentes {
public TestComponentes() {
}
public static void main(String[] args) {
Componente c1 = new Etiqueta("et 1");
Componente c2 = new Etiqueta("et 2");
Componente c3 = new Etiqueta("et 3");
Componente c4 = new Etiqueta("et 4");
Componente c5 = new Etiqueta("et 5");
Componente c6 = new Etiqueta("et 6");
Contenedor a = new Contenedor("Panel 1");
Contenedor b = new Contenedor("Panel 2");
Contenedor c = new Contenedor("Panel 3");
a.add(c1);
a.add(c2);
a.add(c3);
b.add(a);
b.pintar("anaranjado");
c.add(c4);
c.add(c5);
c.add(c6);
c.pintar("verde");
}
}
La salida para la aplicacion anterior seria algo como esto:
Se pinto a et 1 de color anaranjado
Se pinto a et 2 de color anaranjado
Se pinto a et 3 de color anaranjado
Se pinto a Panel 1 de color anaranjado
Se pinto a Panel 2 de color anaranjado
Se pinto a et 4 de color verde
Se pinto a et 5 de color verde
Se pinto a et 6 de color verde
Se pinto a Panel 3 de color verde
Las fuentes del ejemplo:
Si trabajas con Netbeans IDE puedes descargar el proyecto completo:
Read More
Comentarios recientes