domingo, 30 de junio de 2013

Ejemplo Patron Delegate

En esta entrada veremos de forma simple el funcionamiento del patrón Delegate, su uso es muy sencillo y común, tal vez muchos de nosotros trabajamos este patrón sin saberlo ya que va muy de la mano con el manejo de objetos y relación entre clases............ a continuación veremos un ejemplo básico de su aplicación.


¿Que es?


Como dijimos en la entrada sobre patrones de diseño, el patrón delegate Permite extender y reutilizar la funcionalidad de una clase sin utilizar el mecanismo de herencia, donde la Clase C puede acceder a los método de la Clase B por medio de una instancia de esta ultima (No confundir con Bussines Delegate)...

El problema.

Vamos a hacer una aplicación pequeña donde nos piden realizar operaciones matemáticas pero los métodos de dichas operaciones se encuentran en clases diferentes...

La Solución. 

Como nos dicen que los métodos a utilizar se encuentran en diferentes clases podemos utilizar el Patrón Delegate por medio de la relación "Usa" para indicar sobre la asociación y toma de funcionalidades entre la clase principal y las clases con operaciones, delegando la responsabilidad de ejecutar un proceso concreto usando otro objeto con los permisos para realizarlo.

La Aplicación.

El ejemplo es muy simple, vamos a crear una aplicación pequeña donde podamos ingresar 2 números, encontrar el mayor, el menor y posteriormente calcular su división, muy básico pero lo realizaremos usando el patrón Delegate......Veamos

Clase OperacionesMatematicas.

Esta clase tiene el método dividir() que sera la operación principal de nuestra aplicación, posee los atributos numero1 y numero2 que serán heredados por la clase Ingreso desde donde se aplicará el patrón Delegate.
public class OperacionesMatematicas 
{
 public double numero1;
 double numero2;
 
 /**
  * Permite dividir 2 numeros 
  * @param numero1
  * @param numero2
  * @return
  */
   public double dividir(double numero1, double numero2)
  {
    return (numero1/numero2);
  }
}


Clase Organiza.

Esta clase posee los métodos calculaMayor() y calculaMenor(), los cuales reciben los dos números ingresados por el usuario definiendo así el dividendo y el divisor.........como estos métodos son importantes por la aplicación y en vista de que java no posee la herencia múltiple, esta clase sera usada por medio del patrón Delegate para tener acceso a los métodos mencionados.
public class Organiza {
 /**
  * Metodo para calcular el mayor de entre 2 numeros
  * @param a
  * @param b
  * @return
  */
 public double calculaMayor(double a, double b){
  if (a > b)
   return a;
  else
         return b;
 }

 /**
  * Metodo para calcular el menor de entre 2 numeros
  * @param a
  * @param b
  * @return
  */
 public double calculaMenor(double a, double b) {
  if (a < b)
    return a;
  else
   return b;
 }
}

Clase Ingreso.

Esta clase permite obtener los números ingresados por el usuario, Se usa el mecanismo de herencia para obtener la funcionalidad de dividir que se encuentra en la clase OperacionesMatematicas, sin embargo antes de esto necesitamos definir cual es el dividiendo y el divisor por medio de los métodos que se encuentran en la clase Organiza.

Aquí es donde aplicamos el patrón Delegate, ya que como se ha mencionado anteriormente el lenguaje no permite la herencia múltiple así que la única manera de acceder a estos métodos es por medio de la relación "Usa" que provee el patrón Delegate, asi, creando una instancia de la clase Organiza delegamos las funciones al objeto miOrganiza para acceder a los metodos que calculan el numero mayor y el menor....
public class Ingreso extends OperacionesMatematicas
{
 Organiza miOrganiza;
 double mayor,menor;
 public Ingreso()
 {
  miOrganiza=new Organiza();/**delega para emplear la relacion "Usa"*/
 }

 /**
  * Permite el ingreso de 2 numeros enteros para el posterior
  * calculo de su division
  */
 public void ingresar() 
 {
  try {
  numero1=Integer.parseInt(JOptionPane.showInputDialog("valor1: "));
  numero2=Integer.parseInt(JOptionPane.showInputDialog("valor2: "));
  /**Usa miOrganiza para obtener el mayor*/  
  mayor=miOrganiza.calculaMayor(numero1, numero2);
  /**Usa miOrganiza para obtener el menor*/
  menor=miOrganiza.calculaMenor(numero1, numero2);
 
  JOptionPane.showMessageDialog(null,"La division entre:" +
   ""+mayor+"/"+menor+" =  "+dividir(mayor, menor));
  
  } catch (Exception e) {
 JOptionPane.showMessageDialog(null, "Error en el ingreso de datos");
  }
 } 
}


Clase Principal.

Esta clase simplemente contiene el método main() y realiza el llamado a la clase Ingreso, donde inicia la aplicación...

public class Principal {  
  public static void main(String[] args){
   Ingreso miIngreso=new Ingreso();
   miIngreso.ingresar();
 }
}  


Conclusiones.

Como vemos este patrón es muy simple y lo mas normal es que muchos de nosotros lo hayamos utilizado sin saber, básicamente podemos extender nuestro sistema utilizando funcionalidades de otras clases, sin necesidad de utilizar la herencia.........el ejemplo fue muy simple y no tiene mayor grado de complejidad, pero sin importar el contexto de la aplicación en la que se utilice el objetivo será el mismo..... 



También te podría Interesar. 


¿Hay algo que quieras anexar o comentar sobre esta entrada?  no dudes en hacerlo.....y si te gustó, te invito a compartir y Suscribirte ingresando al botón "Participar en este sitio" para darte cuenta de mas entradas como esta ;)

11 comentarios:

  1. Enhorabuena. Me has sacado de un lío. Sigue así chaval.

    ResponderEliminar
    Respuestas
    1. Gracias Tio...... Me alegra que te sirviera, te invito a suscribirte y compartir con tus amigos joer ;)

      Eliminar
  2. Hola, muy bueno...me aclaro la idea, pero me gustaría si me puedes mencionar la diferencia con Bussines Delegate que mencionas al principio del articulo.

    Gracias.
    Christian.

    ResponderEliminar
    Respuestas
    1. Hola, la verdad no he trabajado en si con el bussines Delegate, pero hasta donde se, tiene el mismo principio de delegar procesos pero es un poco mas complejo ya que su uso interviene directamente en aplicaciones cliente servidor, pues permite separar la capa de presentación de la capa de negocio, lo que permite reducir la comunicación entre estas capas cuando se tiene que trabajar con comunicaciones remotas principalmente...... aclaro que el que sean aplicaciones cliente servidor no quiere decir que los patrones que aquí expongo no se puedan usar bajo esos parametros... ;)
      Un Saludo y gracias por comentar , espero que te sirva (y)

      Eliminar
  3. Excelente y en cristiano puro sin complicaciones idiomaticas!!

    ResponderEliminar
  4. Crisitian excelente todos tus post! Tengo una duda, este patrón correspondería al tipo de relación HAS-A?

    ResponderEliminar
  5. yo tengo una duda, en el digrama UML encontre que se utiliza una clase interface.
    Porque tu no la usas en este? que diferencia hay y cuales son sus ventajas y desventajas?
    gran aporte, felicidades¡¡

    ResponderEliminar

Eres libre de realizar cualquier comentario, desde que pueda ayudar con gusto lo atenderé, y si es un critica, bienvenida sea!!!