Ejemplo

El siguiente código es un programa que valida el ingreso de usuarios, pidiendo la contraseña y el nombre del usuario respectivamente. En este programa implementamos el patrón Factory Method y Singleton.

Este programa tiene tres paquetes; un paquete que se llama bd y tiene la clase Conexion, otro que se llama interfaz y que tiene las clases MenuUsuario y Validacion, y por ultimo el paquete llamado logica que tiene las siguientes clases: TipoUsuario, Local, CreadorLocal, Remoto, CreadorRemoto, Corporativo, CreadorCorporativo, Comun, CreadorComun, Creador.

A continuacion veremos la clase Conexion que pertenece al paquete bd.

package bd;


import java.sql.*;
/**
* Clase encargada de realizar la conexion con la base de datos esta misma clase se encarga de consultar y hacer persistencia de datos.
*/
public class Conexion {

static private String bd = "validacionUsuarios";
static private String login = "root";
static private String password = "programacion";
static private String url = "jdbc:mysql://localhost/" + bd;
static private Conexion conex = null;
private String CadenaSql;
private Connection conexion = null;
/**
* el contructor se encargada de realizar la conexion a la base de datos
* y muestra en consola mensajes si se pudo o no conectar a labase de datos.
*/

static public Conexion getConexion() {
if (conex == null) {
conex = new Conexion();
}
return conex;
}
private Conexion() {
try {
System.out.println("Tratando de cargar el driver");
Class.forName("com.mysql.jdbc.Driver");
conexion = DriverManager.getConnection(url, login, password);
if (conexion != null) {
System.out.println("Conexion a base de datos " + bd + " OK");
}
} catch (SQLException sqlEx) {
System.out.println(sqlEx);
} catch (ClassNotFoundException ex) {
System.out.println(ex);
}
}

/**
*
* Funcion encargada de realizar las consultas para poder usarla debe existir
* una conexion a base de datos
*
*
* @return ResultSet
*/
public ResultSet Consultar() {
ResultSet tabla = null;
try {
Statement stmt = conexion.createStatement();
tabla = stmt.executeQuery(CadenaSql);
} catch (SQLException ex) {
System.out.println(ex);
}
return tabla;
}
/**
* Setter que asigna el valor a la cadenaSql
*
* @param String cadena;
*/
public void setCadena(String cadena) {
CadenaSql = cadena;
}
/**
* getter que retorna
*
* @return Connection;
*/
public Connection getConectar() {
return conexion;
}
/**
* Funcion encargada de realizar la desconexion a base de datos
*/
public void desconectar() {
conexion = null;
}
/**
* Funcion encargada de retornar el objeto conexion y garantiza que la clase se instancie una sola vez.
* @return Conexion
* @uml.property name="conexion"
*/
}

ahora la clase MenuUsuario que pertenece al paquete interfaz

package interfaz;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import logica.TipoUsuario;

public class MenuUsuario extends Frame implements ActionListener {

private Button salir;
private JTextArea informacion;
private TipoUsuario relacion;
private Font fuente1;

public MenuUsuario(TipoUsuario datos) {

this.setLayout(null);
this.setResizable(false);
relacion = datos;
this.setTitle("BIENVENIDO " + " ***** " + relacion.getTipoUsuario() + " ***** ");
this.setSize(380, 280);
this.setLocation(200, 70);
this.setBackground(Color.BLACK);

salir = new Button("Salir");
salir.setBounds(160, 210, 70, 40);
salir.addActionListener(this);
add(salir);

informacion = new JTextArea();
informacion.setSize(250, 150);
informacion.setLocation(70, 50);
add(informacion);

fuente1 = new Font("Helvética", Font.ITALIC + Font.ROMAN_BASELINE, 12);
informacion.setFont(fuente1);
informacion.setText(relacion.infor);
this.setVisible(true);
informacion.setForeground(Color.blue);
informacion.setEditable(false);
addWindowListener(new Cierre());
}

public void actionPerformed(ActionEvent e) {
if (e.getSource() == salir) {
System.exit(0);
}
}
}

class Cierre extends WindowAdapter {

@Override
public void windowClosing(WindowEvent e) {
System.exit(0);

}
}

y la clase Validacion que pertenece tambien al paquete interfaz

package interfaz;

import java.awt.event.*;
import java.awt.*;
import javax.swing.JOptionPane;

import logica.*;

public class Validacion extends Frame implements ActionListener {

private Creador creador;
private Label Usuario, Clave;
private TextField txfUs, txfCl;
private Button Salir, Ingresar;
private TipoUsuario us;

public Validacion() {

setLayout(null);
this.setBackground(Color.BLACK);
this.setResizable(false);
Ingresar = new Button("Ingresar");
creador = new CreadorLocal();
us = creador.construir();
Usuario = new Label("USUARIO :");
Usuario.setForeground(Color.white);
txfUs = new TextField(25);
txfUs.setText(null);
txfUs.setBackground(Color.white);
Clave = new Label("CONTRASEÑA :");
Clave.setForeground(Color.white);
txfCl = new TextField(30);
txfCl.setText(null);
Salir = new Button("Cancelar");

add(Usuario);
Usuario.setBounds(30, 60, 90, 20);
add(txfUs);
txfUs.setBounds(195, 60, 170, 20);
txfUs.addActionListener(this);
add(Clave);
Clave.setBounds(30, 90, 90, 20);
add(txfCl);
txfCl.setBounds(195, 90, 170, 20);
txfCl.addActionListener(this);
add(Ingresar);
Ingresar.setBounds(50, 150, 90, 30);
Ingresar.addActionListener(this);
add(Salir);
Salir.setBounds(250, 150, 90, 30);
Salir.addActionListener(this);
addWindowListener(new Cierre());

}

public static void main(String[] args) {
Validacion miIngreso = new Validacion();
miIngreso.setTitle("Validar Usuario y Contraseña");
miIngreso.setLocation(400, 200);
miIngreso.setSize(400, 200);
miIngreso.setVisible(true);
}

public void actionPerformed(ActionEvent e) {

if (e.getSource() == Ingresar) {
if (txfUs.getText().length() != 0 && txfCl.getText().length() != 0) {
us.setNombre(txfUs.getText());
us.setClave(txfCl.getText());
us.capturaRelacion();
if (us.getExistencia() == true) {
if (us.getTipoUsuario().compareTo("local") == 0) {
creador = new CreadorLocal();
us = creador.construir();
}
if (us.getTipoUsuario().compareTo("remoto") == 0) {
creador = new CreadorRemoto();
us = creador.construir();
}
if (us.getTipoUsuario().compareTo("comun") == 0) {
creador = new CreadorComun();
us = creador.construir();
}
if (us.getTipoUsuario().compareTo("corporativo") == 0) {
creador = new CreadorCorporativo();
us = creador.construir();
}
this.dispose();
MenuUsuario MiMenu = new MenuUsuario(us);

} else {
JOptionPane.showMessageDialog(null,
"Usuario y/o contrase�a incorrectos ",
"Ingrese nuavamente sus datos", 0);
}
} else {
JOptionPane.showMessageDialog(
null,
" Existen Campos en blanco, <>",
"Informacion Incompleta", 2);
}
}
if (e.getSource() == Salir) {
System.exit(0);
}
}

class Cierre extends WindowAdapter {

@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
}
y ahora veremos todas las clases del paquete de logica

package logica;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import bd.Conexion;

public class Comun extends TipoUsuario {

private Conexion con;

public Comun() {
tipoUsuario = "Usuario comun";
infor="Usted puede Visualizar:\n\n Usuarios del tipo remoto.\n Usuarios de su mismo tipo.";
}

public String getTipoUsuario() {
return tipoUsuario;
}

public String getInformacion(){
return infor;
}
@Override
public void capturaRelacion() {
existe = false;
conexion.setCadena("SELECT * FROM registro where nombre ='"
+ this.getNombre() + "'");
ResultSet tabla = conexion.Consultar();
try {
while (tabla.next()) {
if (this.getClave().compareTo(tabla.getString("clave")) == 0) {
this.setTipo(tabla.getString("tipoUsuario"));
existe = true;
}
}
} catch (SQLException ex) {
JOptionPane.showMessageDialog(null, "Problemas con la tabla");
}
}
}

package logica;

import java.sql.ResultSet;
import java.sql.SQLException;
import javax.swing.JOptionPane;

public class Corporativo extends TipoUsuario {


public Corporativo() {
tipoUsuario = "Usuario corporativo";
infor="Usted puede:\n\n Visualizar y modificar todos los tipos de usuario ";
}

public String getTipoUsuario() {
return tipoUsuario;
}
public String getInformacion(){
return infor;
}
@Override
public void capturaRelacion() {
existe = false;
conexion.setCadena("SELECT * FROM registro where nombre ='" + this.getNombre() + "'");
ResultSet tabla = conexion.Consultar();
try {
while (tabla.next()) {
if (this.getClave().compareTo(tabla.getString("clave")) == 0) {
this.setTipo(tabla.getString("tipoUsuario"));
existe = true;
}
}
} catch (SQLException ex) {
JOptionPane.showMessageDialog(null, "Problemas con la tabla");
}

}
}

package logica;

public abstract class Creador {

public abstract TipoUsuario factoryMethod();

public TipoUsuario construir() {
TipoUsuario tipoUs = factoryMethod();
return tipoUs;
}
}

package logica;

public class CreadorComun extends Creador{

public TipoUsuario factoryMethod()
{
return new Comun();
}
}

package logica;

public class CreadorCorporativo extends Creador{

public TipoUsuario factoryMethod()
{
return new Corporativo();
}
}

package logica;

public class CreadorLocal extends Creador{

public TipoUsuario factoryMethod()
{
return new Local();
}
}

package logica;

public class CreadorRemoto extends Creador{

public TipoUsuario factoryMethod()
{
return new Remoto();
}
}

package logica;

import java.sql.ResultSet;
import java.sql.SQLException;

import javax.swing.JOptionPane;

import bd.Conexion;

public class Local extends TipoUsuario {


public Local() {
tipoUsuario = "Usuario local";
infor = "Usted puede Visualizar:\n\n Usuarios de su mismo tipo.";
}

public String getTipoUsuario() {
return tipoUsuario;
}

public String getInformacion() {
return infor;
}

@Override
public void capturaRelacion() {
existe = false;
conexion.setCadena("SELECT * FROM registro where nombre ='" + this.getNombre() + "'");
ResultSet tabla = conexion.Consultar();
try {
while (tabla.next()) {
if (this.getClave().compareTo(tabla.getString("clave")) == 0) {
this.setTipo(tabla.getString("tipoUsuario"));
existe = true;
}
}
} catch (SQLException ex) {
JOptionPane.showMessageDialog(null, "Problemas con la tabla");
}
}
}

package logica;

import java.sql.ResultSet;
import java.sql.SQLException;

import javax.swing.JOptionPane;

public class Remoto extends TipoUsuario {

public Remoto() {
this.tipoUsuario = "Usuario remoto";
this.infor="Usted puede Visualizar:\n\n Usarios del tipo comun. \n Usuarios del tipo local. \n Usuarios de su mismo tipo.";
}

@Override
public void capturaRelacion() {
existe = false;
conexion.setCadena("SELECT * FROM registro where nombre ='"
+ this.getNombre() + "'");
ResultSet tabla = conexion.Consultar();
try {
while (tabla.next()) {
if (this.getClave().compareTo(tabla.getString("clave")) == 0) {
this.setTipo(tabla.getString("tipoUsuario"));
existe = true;
}
}
} catch (SQLException ex) {
JOptionPane.showMessageDialog(null, "Problemas con la tabla");
}
}
}

package logica;

import bd.Conexion;

public abstract class TipoUsuario {

static protected TipoUsuario usuario=null;
protected String nombreUsuario;
protected String claveUsuario;
protected String tipoUsuario;
protected boolean existe;
protected Conexion conexion;
public String infor;

public TipoUsuario() {
//Crea una instancia de la clase conexion
conexion = Conexion.getConexion();
existe = false;

}

public String getTipoUsuario(){
return tipoUsuario;
}

public String getNombre() {
return nombreUsuario;
}

public String getClave() {
return claveUsuario;
}

public void setNombre(String nombre) {
this.nombreUsuario = nombre;
}

public void setClave(String clave) {
this.claveUsuario = clave;
}
public boolean getExistencia(){
return existe;
}

public void setTipo(String tipo){
this.tipoUsuario=tipo;
}

public String getInformacion(){
return infor;
}
public abstract void capturaRelacion();
}


Patrones Comportamiento_Memento

Patrón Memento

Sin violar la encapsulación, captura y externaliza el estado interno de un objeto, así el estado del objeto podrá ser restaurado a su estado anterior.

Estructura
Participantes

Memento
  • Almacena el estado interno de un objeto Originator. El Memento puede almacenar mucho o parte del estado interno de Originator.
  • Tiene dos interfaces. Una para Caretaker, que le permite manipular el Memento únicamente para pasarlo a otros objetos. La otra interfaz sirve para que Originator pueda almacenar/restaurar su estado interno, sólo Originator puede acceder a esta interfaz, al menos en teoría.
Originator
  • Originator crea un objeto Memento conteniendo una fotografía de su estado interno.
  • Originator usa a Memento para restaurar su estado interno.
Caretaker
  • Es responsable por mantener a salvo a Memento.
  • No opera o examina el contenido de Memento.
Consecuencias
  • Preservación de los límites de la encapsulamiento.
  • Simplifica al Creador.
  • El uso de mementos puede ser costoso.
  • Definición de interfaces reducidas y amplias.
  • Costes ocultos en el cuidado de los mementos.

Patrones Comportamiento_Visitor

Patrón Visitor

Representa una operación que será realizada sobre los elementos de una estructura de objetos. Visitor permite definir nuevas operaciones sin cambiar las clases de los elementos sobre las que se realiza.

Estructura
Participantes

Visitor: Declara una operación visitar para cada clase de operación ElementoConcreto de la estructura de objetos.
ConcreteVisitor: Implementa cada operación declarada por Visitor.
Element: Define una operación que le permite aceptar la visita de un Visitor.
ConcretElement: Implementa la operación Aceptar que se limita a invocar su correspondiente método del Visitor.
ObjectStructure: Puede enumerar sus elementos y puede proporcionar una interfaz de alto nivel para permitir al Visitor visitar sus elementos.

Consecuencias
  • Facilita la definición de nuevas operaciones.
  • Basta con definir una nueva especialización de la correspondiente clase abstracta Visitor.
  • Las operaciones relacionadas están en el mismo módulo.
  • Esto puede simplificar la realización de los algoritmos y permite que si los algoritmos comparten algunas estructuras de datos, éstas se puedan encapsular en el correspondiente visitor.
  • Se dificulta la definición de nuevos tipos de datos sobre los que han de actuar las operaciones.
  • Cada nuevo tipo de datos significa la definición de un método en Visitor y otro en cada uno de los ConcreteVisitor.

Patrones Comportamiento_ChainOfResponsability

Patrón Chain of Responsability

Evita ligar al emisor de una petición y al receptor de la misma dando a más de un objeto la posibilidad de gestionar la petición. Encadena los objetos receptores y va pasando las peticiones a lo largo de la cadena hasta que un objeto la maneje.

Motivación
  • Hay algunos objetos con métodos similares que pueden ser apropiados para la acción que el programa reclama. Sin embargo, es más apropiado que los propios objetos decidan cual es el que va a llevar a cabo la acción en vez de construir ésta decisión en el código de llamada.
  • No se quiere construir estructuras del tipo if-else o switch-case.
  • Es probable que existan nuevos objetos que queramos añadir a la lista de opciones de procesamiento mientras el programa se está ejecutando.
  • Debe utilizarse cuando más de un objeto tiene que actuar sobre una llamada y no queremos construir el conocimiento de estas interacciones dentro del programa cliente.
Estructura

Participantes


Handler: Define una interfaz para tratar las peticiones , implementa el enlace al sucesor.
ConcreteHandler: Trata las peticiones de las que es responsable, puede acceder a su sucesor. Si el ConcreteHandler puede manejar la petición, lo hace, en caso contrario la reenvía a su sucesor.
Client: Inicializa la petición a un objeto ConcreteHandler de la cadena.


Consecuencias

Ventajas e inconvenientes de este patrón:
  • Reduce el acoplamiento.
  • Añade flexibilidad para asignar responsabilidades a objetos.
  • No se garantiza la recepción.

Patrones Comportamiento_Template Method


Patrón Template Method


Define el esqueleto de un algoritmo, dejando algunos pasos a las subclases. Template Method permite a las subclases redefinir ciertos pasos de un algoritmo sin cambiar la estructura del algoritmo.

Estructura

Participantes

AbstractClass: Una clase en este papel tienen un método concreto que contiene la lógica de alto nivel (el esqueleto del algoritmo) de la clase. Este es el método plantilla indicado en el diagrama. Este método llama a otros métodos, definidos en la clase AbstractClass como métodos abstractos, que invocan a la lógica de bajo nivel que varia para cada subclase de la clase AbstractClass.
ConcreteClass: Una clase en este papel es una subclase concreta de una clase AbstractClass. La clase AbstractClass sobrescribe los métodos abstractos definidos en su superclase y proporciona la lógica necesaria (los pasos del algoritmo) para completar la lógica del método plantilla.

Patrones relacionados

Strategy El patrón Strategy modifica la lógica de los objetos individuales. El patrón
Template Method modifica la lógica de una clase entera.

Patrones Comportamiento_Strategy

Patrón Strategy

Define una familia de algoritmos, encapsula cada uno de ellos y los hace intercambiables. Strategy permite al algoritmo variar independientemente de los clientes que lo utilicen.

Estructura
Participantes

Strategy: Declara una interfaz común a todos los algoritmos soportados.
ConcreteStrategy: Implementa el algoritmo que usa la interfaz strategy.
Context: Se configuran con un objeto ConcreteStrategy. Mantiene una referencia a un objeto Strategy. Puede definir una interfaz que permite acceder a sus datos.

Consecuencias
  • Permite que los comportamientos de los objetos Cliente sean determinados dinámicamente sobre un objeto base.
  • Simplifica los objetos Cliente para deducirlos de alguna responsabilidad para seleccionar comportamientos o implementaciones de comportamientos alternativos. Esto simplifica el código de los objetos Cliente eliminando las expresiones if y switch. En algunos casos, esto puede incrementar también la velocidad de los objetos Cliente porque ellos no necesitan perder tiempo seleccionado un comportamiento.
Patrones relacionados

Adapter: El patrón Adapter es estructuralmente similar al patrón Strategy. La diferencia esta en el objetivo. El patrón Adapter permite a un objeto Cliente sacar su función pretendida originalmente mediante llamadas a métodos de objetos que implementa un interface particular. El patrón Strategy proporciona objetos que implementa un interface particular con el propósito de alterar o determinar el comportamiento de un objeto Cliente.
Flyweight: Si hay muchos objetos Cliente, los objetos StrategyConcreto pueden estar
mejor implementados como Flyweights.
Template Method: El patrón Template Method maneja comportamientos alternativos a través de subclases más que a través de delegación.

Patrones Comportamiento_State

Patrón State

Permite a un objeto cambiar su comportamiento cuando cambia su estado interno. El objeto parecerá pertenecer a otra clase.

Aplicabilidad
  • El comportamiento de un objeto es determinado por un estado interno que cambia en respuesta a los eventos. Debe cambiar su comportamiento en tiempo de ejecución cuando cambie su estado.
  • La organización de la lógica que maneja un estado de un objeto debería ser capaz de cambiar a muchos estados sin llegar a ser una gran cantidad de código inmanejable.
  • Las operaciones tienen sentencias condicionales largas que dependen del estado del objeto. Este estado es representado por una constante enumerada. A menudo, varias operaciones contendrán esta misma estructura condicional. Este patrón sitúa cada rama de la sentencia condicional en una clase separada. Esto permite tratar el estado de un objeto como un objeto que puede variar de forma independiente a otros objetos.
Estructura
Participantes

Context: es una clase cuyas instancias exponen el comportamiento de los estados. Define la interfaz para los clientes. Las instancias de la clase Context determinan su estado actual manteniendo una referencia a una instancia de una subclase concreta de la clase State. La subclase de la clase State determina el estado.
State: es la superclase de todas las clases utilizadas para representar el estado de los objetos contexto. Define una interfaz para encapsular el comportamiento asociado con un estado particular del contexto.
StateConcretoA, StateConcretoB: Estas clases son subclases concretas de la clase State. Cada subclase implementa un comportamiento asociado con un estado del contexto.

Consecuencias
  • Localiza el comportamiento dependiente del estado.
  • Hace explícitas las transiciones entre estados.
  • Los objetos Estado pueden compartirse.
Patrones relacionados

Flyweight: Se puede utilizar el patrón Flyweight para compartir objetos estado, para soportar un gran número de objetos de forma eficiente. Este patrón explica cuando y como se puede compartir un estado.
Mediator: podemos utilizar el patrón State con el patrón Mediator cuando implementamos las interfaces de usuario.
Singleton: Se pueden implementar estados utilizando el patrón Singleton.

Patrones Comportamiento_Observer

Patrón Observer

Define una dependencia 1:M entre objetos para que cuando uno cambie su estado, a todos sus dependientes les sea notificado el cambio y se actualicen automáticamente.

Motivación

Mantener la consistencia entre objetos relacionados, sin aumentar el acoplamiento entre clases.
Ejemplo: separación de la capa de presentación en una interfaz de usuario de los datos de aplicación subyacentes

Estructura
Participantes

Subject: Conoce a sus observadores, que pueden ser un número arbitrario. Proporciona una interfaz para añadir y quitar objetos observadores.
Observer: Define la interfaz de los objetos a los que se debe notificar cambios en un sujeto.
ConcreteSubject: Almacena el estado de interés para sus observadores. Envía notificaciones a sus observadores cuando su estado cambia.
ConcreteObserver: mantiene una referencia a un ConcreteSubject, almacena el estado del sujeto que le resulta de interés, implementa Observe para mantener su estado consistente con el sujeto.

Consecuencias
  • Permite modificar sujetos y observadores de manera independiente.
  • Reutilizar un sujeto sin reutilizar sus observadores, y viceversa.
  • Añadir observadores sin tener que cambiar el sujeto ni los demás observadores.
  • Acoplamiento abstracto entre el sujeto y el observador. El sujeto no sabe la clase concreta de sus observadores (acoplamiento mínimo).
  • Soporte para broadcast. El sujeto envía la notificación a todos los observadores suscritos. Se pueden añadir/quitar observadores.
  • Actualizaciones inesperadas. Una operación en el sujeto puede desencadenar una cascada de cambios en sus observadores. El protocolo no ofrece detalles sobre lo que ha cambiado.
Patrones relacionados

Adapter: El patrón Adapter puede ser utilizado para permitir a los objetos que no implementen el interface requerido participar en el patrón Observer para recibir notificaciones.
Delegation: El patrón Observer utiliza el patrón Delegation.
Mediator: El patrón Mediator es utilizado algunas veces para coordinar cambios de estado inicializados por múltiples objetos a un objeto Observable.

Patrones Comportamiento_Mediator

Patrón Mediator

Define un objeto que encapsula como interactúan un conjunto de objetos. Las comunicaciones entre objetos se realizan a través del Mediator.

Motivación

Cuando muchos objetos interactúan con otros objetos, se puede formar una estructura muy compleja, con objetos con muchas conexiones con otros objetos. En un caso extremo cada objeto puede conocer a todos los demás objetos.

Para evitar esto el patrón Mediator encapsula el comportamiento de todo un conjunto de objetos en un solo objeto.

Los objetos envían y reciben peticiones a través del mediador, este patrón implementa el comportamiento cooperativo encaminando esas peticiones a los objetos apropiados.

Estructura
Participantes

Mediador: define una interfaz para comunicarse con los otros objetos.
Mediador concreto: Implementa el comportamiento cooperativo entre los Objetos. Conoce a los Objetos.
Objetos: Cada objeto conoce su mediador, y usa a este para comunicarse con otros objetos.

Consecuencias
  • Reduce la herencia.
  • Desacopla a los “Colegas”.
  • Simplifica los protocolos de los objetos.
  • Abstrae cómo cooperan los objetos.
  • Centraliza el control

Patrones Comportamiento_Iterator


Patrón Iterator


Proporciona una forma de acceder a los elementos de un objeto compuesto secuencialmente sin conocer su diseño.

Estructura

Participantes

Iterator: Define una interfaz para recorrer los elementos.
ConcreteIterator: Implementa la interfaz iterator.
Aggregate: Define una interfaz para crear un objeto iterador.
ConcreateAggregate: Implementa la interfaz de creación del iterador.

Colaboraciones

Un iterador concreto lleva registro del objeto actual en el agregado y determina el objeto siguiente en el recorrido.

Consecuencias
  • Soporta variaciones en el recorrido de un agregado.
  • Los iteradores simplifican la interfaz del agregado.
  • Puede haber más de un recorrido pendiente.

Patrones Comportamiento_Interpreter

Patrón Interpreter

Dado un lenguaje, define una representación para su gramática junto con un intérprete que usa la representación para interpretar sentencias del lenguaje.

Estructura
Participantes

AbstractExpression: declara las operaciones de interpretación que las especializaciones han de implementar.
TerminalExpression: representan a los símbolos terminales.
NonterminalExpression: representan a las producciones de la gramática.
Context: contiene la información global del proceso de interpretación.
Client: construye el árbol sintáctico de una frase del lenguaje e invoca la operación de interpretación.

Consecuencias
  • Es fácil cambiar y ampliar la gramática.
  • Resulta fácil implementarla.
  • Las gramáticas complejas son difíciles de mantener.
  • Añadir nuevos modos de interpretar expresiones.

Patrones Comportamiento_Command


Patrón Command


El objetivo de este patrón es encapsular una petición en un objeto para tener un control más fino sobre la petición. Se le conoce también como: Action, Transaction, Orden.
Motivación

La necesidad de un paquete de herramienta de interfaz de usuarios con botones, menús sin saber que van a hacer en la aplicación Solución: encapsula la petición en un objeto como una orden – la clave es una clase abstracta Orden que tenga una interfaz para ejecutar operaciones.

Estructura

Participantes

Command: declara una interfaz para ejecutar una operación.
ConcreteCommand: define un enlace entre un objeto “Receiver” y una acción. Implementa “Execute” invocando la(s) correspondiente(s) operación(es) del “Receiver”.
Client: Crea un objeto “ConcreteCommand” y establece su receptor.
Receiver: sabe como llevar a cabo las operaciones asociadas a una petición. Cualquier clase puede hacer actuar como “Receiver”.
Invoker: le pide a la orden que ejecute la petición.
Consecuencias
  • Comando desacopla a los objetos que invocan la operación del objeto que sabe como realizarla.
  • Los comandos pueden ser extendidos.
  • Es fácil agregar nuevos comandos porque no hay que cambiar las clases existentes.
Patrones relacionados

Factory Method: Ofrece una forma alternativa de llamar a los órdenes además del uso del command manager.
Intérprete: Se puede implementar un pequeño Intérprete mediante clases Command.
Template Method: Sirve para implementar la lógica de “Deshacer” de forma automática.
Composite y Prototype: Permite realizar agrupaciones de órdenes de forma similar a una macro. Hay quien lo utiliza para implementar la copia de la orden al histórico de órdenes.