12.24.07

Acercándonos al patrón Façade, veamos el patrón Factory

Posted in .NET, Patrones, Programación at 1:01 pm by Miguel

Unos post más atrás (si no recuerdo mal hablando de .NET Remoting) surgió en la conversación el patrón Façade. Es más,incluso se adjuntó un diagrama de arquitectura donde veíamos implementado el patrón dando vida a la convivencia de servicios web y servicios de remoting en la misma arquitectura.

En su día prometí dedicar un post al patrón Façade, pero como este implementa otro patrón llamado Factory, creo que mejor antes vamos a por el Factory para luego atacar Façade con un poco más de base.

El patrón Factory entra en el grupo de patrones de creación (donde también podemos encontrar Singleton del cual ya hemos hablado también en otros post). Los patrones de creación, tal como su nombre indica, se dedica a crear objetos y a encapsular dicha creación para abstraernos de la misma (lo de siempre quitar trabajo, elevar la productividad y la mantenibilidad).

Os dejo aquí un PDF interesante al respecto de los patrones de creación por si os interesa el tema a fondo, vienen bastantes ejemplos.

http://www.dei.inf.uc3m.es/docencia/p_s_ciclo/tdp/curso0203/apuntes/factory.pdf

De todas maneras, lo de siempre, yo os voy a dejar una muestra muy pequeña que os sirva de punto de partida y ya luego si os interesa a fondo os metéis a saco teniendo la base ya firme.

Antes de empezar, contaros que hay tres tipos de patrones Factory: Simple Factory, Factory Method y Abstract Factory y aquí en principio sólo vamos a hablar de Simple Factory ya que es el patrón que usa Façade, que es a lo que queremos llegar.

Aprovecho y hago un inciso, es importante en esta profesión centrarse en el problema y no irse por las ramas, si sabéis que algo soluciona vuestro problema, a por ello, no os pongáis a mirar y mirar y mirar, porque el tiempo se os va a ir y la fecha de entrega de un proyecto suele ser fija :) Fin del inciso.

Factoría Simple + Strategy (mira tú por donde nos aparece otro patrón)

Allí va un ejemplo, a ver si quedan las cosas claras.

Primero una interfaz Vehículo (código C#):

public interface Vehiculo
{
 public void Arrancar();
 public void Frenar();
 public void GirarIzquierda();
 public void GirarDerecha();
}

Como véis la interfaz vehículo lo que hace es definir una serie de comportamientos comunes a cualquier vehículo.

Ahora implementemos dos vehículos.

public class Coche : Vehiculo
{
 public void Arrancar()
 {
  // Código necesario para arrancar el coche.
 }

 … Resto de métodos de Vehículo …
}

public class Moto : Vehiculo
{
 public void Arrancar()
 {
  // Código necesario para arrancar la moto
  // que no es igual al del coche claro
 }

 … Resto de métodos de Vehículo …
}

Como véis lo único que hemos hecho aquí es implementar los métodos de un vehículo para un coche y una moto. Hemos definido cómo actúan cada uno por separado. Hemos encapsulado dicho comportamiento en las clases que heredan de vehículo.

Y ahora ya “la magia”, la factoría que genera vehículos:

public class FactoriaVehiculo
{
 public static Vehiculo GetVehiculo (TipoEnumeradoVehiculo vehiculo)
 {
  switch (TipoEnumeradoVehiculo)
  {
   case vehiculo.Coche:
    return new Coche();
    break;
   case vehiculo.Moto:
    return new Moto();
    break;
   default:
    return null;
    break;
  }
 }
}

Hemos utilizado un Tipo Enumerado auxiliar para hacer esto más legible y sobre todo más encapsulado. Otra opción era pasarle a GetVehículo un String… pero claro, estamos en lo de siempre, si le pasamos un string estamos dando por hecho que sabemos que hace por dentro la factoría, cuando no tiene por qué ser así.

Bien, por último, vamos a crear un procedimiento que utilice la factoría, para así acabar de darle forma al asunto:

public void EjemploFactoria()
{
 // lista genérica, SIEMPRE QUE SEA POSIBLE
 List<Vehiculo> listaVehiculos = new List<Vehiculo>;
 
 // añadimos vehículos a la lista genérica
 listaVehiculos.add(FactoriaVehiculo.GetVehiculo((TipoEnumeradoVehiculo.Coche));
 listaVehiculos.add(FactoriaVehiculo.GetVehiculo((TipoEnumeradoVehiculo.Moto));
 listaVehiculos.add(FactoriaVehiculo.GetVehiculo((TipoEnumeradoVehiculo.MotoConSidecar));
 listaVehiculos.add(FactoriaVehiculo.GetVehiculo((TipoEnumeradoVehiculo.TodoTerreno));

 // recorremos la lista de vehículos
 foreach (Vehiculo unVehiculo in listaVehiculos)
 {
  unVehiculo.Arrancar();
 }

}

¿Queda claro? La factoría ha ocultado cómo se crean las clases y las ha devuelto ya generadas. Por cierto, hemos hablado antes del patrón Strategy… ¿pero dónde aparece? Pues lo vemos en funcionamiento en la línea unVehiculo.Arrancar(). Cada vehículo arrancará como tenga definido, esa es su estrategia. Strategy es un patrón muy simple y que seguramente habréis implementado muchas veces pero sin haberlo llamado nunca así :) Os dejo el link de la wikipedia al respecto aquí para que le echéis un ojo.

Por cierto, menudo ejemplo de polimorfismo nos ha salido también, ¿no? Ahora que caigo, ¿podríamos definir el polimorfismo como sinónimo de patrón strategy? Tengo que investigarlo.

Más cosas también para terminar, en otros posts también se habló de crear factorías de DAO’s, ¿se ve ahora un poco mejor el tema?

¡Saludos a todos y feliz navidad!

Miguel.

Rating 3.50 out of 5
[?]

12.20.07

Buenas Prácticas: Los servicios web no deberían devolver tipos específicos de la tecnología

Posted in .NET, Arquitectura, Buenas Prácticas, Java, Programación, Servicios Web, Web at 11:32 pm by Miguel

Típico ejemplo de esta situación es un servicio web hecho en .NET que devuelve un Dataset.

Si se nos garantiza que el consumidor del servicio va a ser siempre un cliente .NET aún la cosa se sostiene un poco. El problema es si por ejemplo intentamos consumir un servicio que da un Dataset por otra tecnología que no es .NET.

Para los que tengáis experiencia trabajando con servicios sabréis que una vez que creas un servicio que devuelve un objeto o tiene por parámetro un objeto definido en el servicio, desde el cliente que consume el servicio tenemos visibilidad sobre la definición de dicho objeto. Si yo tengo un servicio que recibe por parámetro un objeto coche, yo desde el cliente puedo rellenar dicho objeto coche y pasárselo por parámetro al servicio. Lo mismo ocurre si el coche me lo devuelve el servicio, yo puedo conocer sus propiedades y extraer los valores de las mismas.

¿Pero qué ocurre con un dataset? ¿Ocurre lo mismo? Pues no.

El principal problema de un Dataset es que en tiempo de diseño no conocemos cuál es su contenido. Sólo lo sabemos en tiempo de ejecución. Ya “sólo” por este “pequeño” problema tenemos ya un agujero del tamaño de un tonel respecto a la protección de tipos en tiempo de diseño. Podemos pedirle lo que quiera al dataset, porque el compilador no va a darnos ningún tipo de alarma, nos vamos a enterar en tiempo de ejecución generando una excepción si la consulta sobre el dataset no era correcta.

Este problema se vuelve más complicado aún si consumimos el servicio desde por ejemplo un cliente java, ya que para interpretar el contenido del dataset en tiempo de ejecución no nos va a quedar más remedio que leer el mensaje xml que nos llega con el contenido, leerlo e interpretarlo a pelo.

¿Cual es entonces mi recomendación? No es difícil respuesta adivinarlo si leéis los artículos de esta web, por mi parte está claro, Data Transfers Objects :) O Value Objects, que es lo mismo :)

Saludos!

Miguel.

Rating 3.00 out of 5
[?]

12.16.07

El negocio es el negocio

Posted in Arquitectura, Servicios Web at 11:58 am by Miguel

En el artículo anterior ya estuvimos comentando que lo de la arquitectura orientada a servicios está hoy en día hasta en la sopa, que no hasta en la SOAP (chiste malo).

Qué bonito es lo de la orientación a servicios, vamos a encapsular el negocio, pero… ¿tenemos todos claro qué es lo que tenemos que almacenar en el negocio?

Lo comento porque es un error bastante común pensar que en el negocio de nuestra arquitectura orientada a servicios debemos almacenar por ejemplo nuestro acceso a datos de forma encapsulada. Me explico con un ejemplo. Pongamos que tenemos un servicio que compra un coche, el cual a la hora de llamarlo crea una nueva entrada en la tabla “Compra”. Pero claro, cuando compramos un coche no sólo tenemos que registrarlo en la tabla “Compra” si no que seguramente tendremos que trabajar con el Stock, y dependiendo de nuestro Stock tal vez tengamos que hacer una petición de nuevo Stock. Además, puede darse el hecho que según la petición de nuestro cliente la compra la haga financiada y la compra financiada le obligue a pagar un seguro de vida por cada uno de los meses que se le esté financiado la compra.

Wou, cuantas cosas. ¿Esto quiere decir que tenemos que hacer un servicio web por cada uno de las posibilidades que hablábamos en el anterior párrafo? Pues no, eso es un error de concepto de cómo usar la capa de negocio. La capa de negocio tiene que encapsular el negocio, es decir, ocultarlo a los consumidores del mismo.

Si uno de los clientes que llama al servicio web quiere comprar un coche llamará al servicio web de compra de coche pero no se va a preocupar de todas la otra casuística del stock y de la financiación y toda la historia, porque de eso no sabe nada. Nuestro consumidor del servicio no tiene por qué saber cómo funciona nuestro negocio, eso es cosa nuestra. El servicio web se encargará de todo internamente abstrayendo al cliente. 

¿Se entiende el concepto?

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

12.13.07

ESB (Bus de Servicios Empresariales) + SOA (Arquitectura Orientada a Servicios)

Posted in Arquitectura, Servicios Web, Web at 10:57 pm by Miguel

Mira tú que bien hoy vamos a aumentar un poco nuestro vocabulario, y a parte de poder hablar de SOA (arquitectura orientada a servicios) algo que últimamente está en la boca de todos, vamos a poder hablar también de ESB (bus de servicios empresariales).

Más abajo os voy a dejar un link donde se explica qué es un ESB mucho más a fondo de lo que os voy a contar yo, pero antes, me gustaría al menos daros unas pinceladas con las principales ventajas que ESB nos ofrece, para que tengáis un poco las cosas enfocadas antes de abordar la lectura más técnica.

Imaginaos que habéis creado una aplicación orientada a servicios, donde vuestra capa de negocio permanece a parte de vuestra capa presentación y de vuestro modelo. La gran ventaja que esto supone será ya conocida por muchos, los servicios que provee la capa de negocio podrán ser consumidos por cualquier aplicación que pueda acceder al servidor de negocio y no únicamente por la aplicación que vosotros habéis creado. Esto añade valor a vuestra aplicación, la hace reutilizable y al mismo tiempo mantenible. Por supuesto además incorpora todas las ventajas de usar SOA, independencia de dispositivo, plataforma, adiós al problema de los firewall al utilizar el puerto 80 y blablabla…

Hagamos otro esfuerzo de imaginación y pensemos el caso de que llevamos en nuestra empresa ya 10 aplicaciones orientadas a servicios, al menos una por cada uno de los departamentos que conforman nuestra empresa. ¿Cuántos servicios podemos tener ya en marcha? ¿100? ¿500? ¿1000? Esto empieza a hacerse algo inmanejable, ¿no?

Ante esta situación se nos presentan varios problemas:

1) Catálogo de servicios inmanejable. ¿Cómo nos organizamos teniendo 1000 servicios en marcha?
2) Múltiples conexiones punto a punto. Por cada uno de las aplicaciones de servicios con las que quiero trabajar necesito una conexión puto a punto con ella. Necesita saber exactamente dónde está.
3) Seguridad. ¿De verdad quiero que se tenga visibilidad sobre todo el catálogo de servicios disponibles?

Bien, pues ahora, si os sigue interesando el tema de los buses de servicios empresariales, aquí abajo tenéis un PDF donde en las primeras hojas tenéis una descripción mucho más concisa del tema :)

http://www.tibco.com/international/spain/resources/es_esb_for_soa.pdf

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

12.11.07

¿Un master?

Posted in Personal at 9:35 pm by Miguel

Es todavía una posibilidad, el tiempo dirá si al final toma forma.

MBA-TECH: Gestión y Dirección de las TIC

http://www.universidadsanjorge.net/sitio/software.php

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

12.10.07

Javascript Intellisense y Debuging en Visual Studio 2008

Posted in .NET, Herramientas, Javascript, Programación, Web at 11:58 pm by Miguel

Esto necesita una post como una catedral de grande.

¡Parece que la nueva versión de Visual Studio 2008 va a incoporar de serie debug e intellisense para Javascript!

¿Va a servir esto para mejorar la productividad de los desarrollos en javascript? ¿Va a provocar que abusemos de ellos?

Al fin y al cabo una gran noticia que tal vez quede algo escondida detrás del bombo que se le está dando a LINQ.

Más información en http://msdn2.microsoft.com/es-es/vstudio/default(en-us).aspx

Saludos.

Rating 3.00 out of 5
[?]

12.09.07

Programación Genética

Posted in Inteligencia Artificial, Programación at 8:26 pm by Miguel

En su día, estudiando inteligencia artificial, me llamó bastante la atención el tema de la programación genética.

El otro día paseando por ahí encontré un PDF que me llamó bastante la atención al respecto.

http://www.sia.eui.upm.es/grupos/PG.pdf

Lo comparto con vosotros.

Por cierto, después de leerlo (a los que no os gusten las matemáticas como a mi tal vez se os haga algo pesado)… ¿se os ocurre algún ejemplo de cómo aplicar estas técnicas a la programación de aplicaciones de gestión?

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

12.05.07

Homenaje a la Recursividad

Posted in Javascript, Programación, Web at 9:45 pm by Miguel

Tengo que admitir que la última asignatura que conseguí sacarme de la carrera fue una en la que el 60% del valor de la nota del examen era un problema de recursividad.

La verdad es que imaginaos que muy bien no me caía el tema, porque además me costó más de un intento el sacar el aprobado. Con ello la verdad es que le pillé algo de manía a la recursividad, y a parte de utilizarla para hacer bucles programando en LISP en contadas ocasiones la he vuelto a aplicar.

Pero, todo llega, y reciéntemente me he topado con el siguiente código javascript:

function toggleDisabled(el)
{
               
  try
  {
    el.disabled = el.disabled ? false : true;
  }
  catch(E){}
               
  if (el.childNodes && el.childNodes.length > 0)
  {
    for (var x = 0; x < el.childNodes.length; x++)
    {
      toggleDisabled(el.childNodes[x]);
    }
  }

}

La verdad es que menuda maravilla, esto hay que aplicarlo más a menudo. Todo sea por seguir aprendiendo.

Por cierto, pregunta, ¿qué hace el código que hay ahí arriba? :)

El detalle de meter en un try el enable y comerse el catch la verdad es que llama especialmente la atención, es una solución algo bruta pero que deja el código elegante. Lo único que… yo le hubiera añadido un comentario por algún lado… por eso de dejarlo más claro.

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

Dos reflexiones sobre la programación en objetos

Posted in Programación at 9:33 pm by Miguel

Si para entender lo que hace una clase necesitas mirar su implementación interna, algo falla.

Si cambiando la implementación interna de tu clase las llamadas que hacías a sus métodos públicos han dejado de funcionar pueden haber ocurrido dos cosas, o te equivocaste cambiando la implementación interna o tu clase no está bien encapsulada.

Saludos.

Miguel.

Rating 3.00 out of 5
[?]

12.03.07

Haciendo nuestros Data Access Object (DAO) transparentemente transaccionales

Posted in Patrones, Programación at 9:07 pm by Miguel

Y lo prometido es deuda, aquí viene un pequeño artículo con una idea para hacer las llamadas a vuestros DAOs transaccionales de forma totalmente transparente.

Hasta ahora por lo que habíamos visto éramos capaces conociendo y aplicando los patrones DAO+DTO de encapsular nuestras llamadas al modelo de negocio, ordenarlas cada una en su DAO correspondiente, garantizar una única instancia de cada uno de los DAO utilizando un Singleton… y algunas cosillas más.

Pero algo que nos quedaba pendiente resolver era cómo hacer que las llamadas a nuestros DAO se llevaran a cabo de forma transaccional. Es decir, que en caso de que en varias llamadas consecutivas a nuestros DAO (llamdas que alteren el contenido de una entidad de destino), podamos volver al estado anterior en caso de que ocurra un error en la aplicación.

Me explico. Por lo que conocíamos por ahora podíamos hacer lo siguiente.

try
{

 // insertamos tres coches
 CocheDAO.GetInstance().Insert(codigocoche1, “seat”);
 CocheDAO.GetInstance().Insert(codigocoche2, “mercedes”);
 CocheDAO.GetInstance().Insert(codigocoche3, “renault”);

 // actualizamos el coche 2
 CocheDAO.GetInstance().Update(codigocoche2, “honda”);

 // borramos el coche 1
 CocheDAO.GetInstance().Delete(codigocoche1);

}
catch (Exception ex)
{
 TratarExcepcion(ex);
}

Y qué ocurre si al insertar el coche número 3 la aplicación falla. Pues que se habrán creado dos coches que quedarán colgados en la base de datos. ¿Cómo solucionamos esto? Creando una transacción. Pero claro, entonces aquí viene el gran problema… ¿de dónde narices saco la transacción si no tengo acceso a la conexión de base de datos? Este es el chiste del DAO, que no veo la conexión, es totalmente transparente a mi… entonces… ¿cómo voy a hacer algo transaccional?

Entonces es cuando aparece la idea feliz y nos inventamos unas transacciones propias para los DAO. Algo así como un TransactionDAO. Entonces nuestro código anterior cambia un poco y pasa a ser el siguiente:

try
{

 TransactionDAO tran = BaseDAO.BeginTransaction();

 // insertamos tres coches
 CocheDAO.GetInstance().Insert(tran, codigocoche1, “seat”);
 CocheDAO.GetInstance().Insert(tran, codigocoche2, “mercedes”);
 CocheDAO.GetInstance().Insert(tran, codigocoche3, “renault”);

 // actualizamos el coche 2
 CocheDAO.GetInstance().Update(tran, codigocoche2, “honda”);

 // borramos el coche 1
 CocheDAO.GetInstance().Delete(tran, codigocoche1);

 tran.Commit();

}
catch (Exception ex)
{
 tran.Rollback();
 TratarExcepcion(ex);
}

Parece esto una llamada a transaccional típica, ¿no? Pero hay una sustancial diferencia, es que la transacción no es una transacción de base de datos que nos pueda proveer por ejemplo .NET (SqlTransaction) si no que es una transacción propia del DAO y que nos provee para hacer las llamadas transaccionales. El cómo implemente internamente la transacción el DAO ya es problema suyo, y me explico. En el caso que el DAO esté atacando a una base de datos internamente implementará una arquitectura trabajando con SqlCommand y SqlTransaction… pero… ¿y si está llamando a Servicios Web? ¿Y si está atacando a ficheros de texto? ¡¡Pues ya lo definirá internamente!! Eso es totalmente transparente a la capa que llama a los DAO.

En el caso del ejemplo hemos implementado llamadas a métodos BeginTransaction, Rollback y Commit en nuestro BaseDAO, que es el que internamente gestiona las transacciones. ¿Cómo puede funcionar esto internamente? Pues por ejemplo manteniendo BaseDAO una lista genérica de de TransaccionDAO, la cual irá aumentando y disminuyendo a medida que los clientes pidan y confirmen transacciones.

Tal vez quede perfilar un poco más cómo maneja BaseDAO ese pool de transacciones… eso lo haremos en otro artículo. Dejo alguna pregunta abierta ¿qué ocurre si creamos transacciones y luego no hacemos rollback o commit de ellas? Deberiamos currarnos la caducidad de dichas transacciones…

Saludos.

Miguel.

Rating 3.00 out of 5
[?]