Showing posts with label Design Patterns. Show all posts
Showing posts with label Design Patterns. Show all posts

Sunday, January 31, 2010

Qi4j y Programación Orientada a Compuestos

Hace unas semanas un amigo me recomendó esta pagina de un nuevo framework Qi4j que se centra en el desarrollo del modelo de dominio y usa conceptos de AOP, DI (Dependency Injection) y DDD (Domain Driven Design).

El framework es una implementación de un nuevo paradigma de programación que es la Programación Orientada a Compuestos (Composites) (COP - por sus siglas en Ingles) usando Java 5 puro.

Los principios de la COP son:
- El comportamiento de un objeto depende del contexto.
- El desacoplamiento es una virtud.
- Las reglas de negocio importan mas.
- Las Clases han muerto, larga vida a las Interfaces.

Ellos argumentan que la Programación Orientada a Objetos (OOP) tiene ciertos problemas para realmente modelar el ciclo de vida de los objetos. Por ejemplo, un objeto no siempre tiene los mismos atributos y estos pueden variar (tener menos o mas atributos) en el tiempo, incluso el comportamiento de un objeto no es el mismo siempre ya que puede variar según el contexto donde se encuentre ejecutando.

Este tipo de cosas ha sido muy difícil implementarlas usando OOP y aunque se pueden implementar debería ser mas "natural".

A todos nos ha pasado que empezamos un sistema haciendo el análisis de los conceptos y reglas de negocio y buscamos hacer un diseño que represente y cumpla con todos esos requisitos lo mejor posible. Pero cuando llega la hora de codificar terminamos enfocando mas nuestros esfuerzos en la infraestructura y terminamos teniendo un modelo de dominio anémico (Martin Fowler explica esto aquí).

La Programación Orientada a Compuestos esta muy influenciada por el libro de Erick Evans (Domain Driven Design) donde propone conceptos y patrones de diseño para diseñar sistemas mas enfocados al modelo de dominio.

En la COP existen dos niveles de composición:

- Un nivel de composición para ensamblar objetos compuestos a partir de piezas mas pequeñas llamadas Fragmentos.
- Y un segundo nivel de composición para ensamblar Módulos a partir de compuestos (objetos del primer nivel de composición), Capas a partir de Módulos y terminar con una Aplicación compuesta de Capas.

Los Fragmentos a partir de los cuales se puede formar un objeto compuesto son:
- Mixins. Representan el estado de un objeto compuesto.
- Restricciones (Constraints). Reglas de validación tanto de entrada como de salida para los argumentos.
- Intereses (Concerns). Interceptan llamadas de métodos. Su uso se aplica generalmente a comportamientos que aplican a todo el sistema (cross-cutting behaviours).
- Efectos Secundarios (Side Effects). Se ejecutan después de la ejecución de un método pero no influyen en los datos de salida que entregan los métodos.

En fin, el framework Qi4j se ve muy interesante y vale la pena echarle un ojo para ver la forma en que trabaja.

Links de interés:

- Resumen del libro de Erick Evans DDD. http://www.infoq.com/minibooks/domain-driven-design-quickly

Friday, January 11, 2008

Domain-Driven Design: Entities & Value Objects

Eric Evans en su libro "Domain-Driven Design: Tackling Complexity in the Heart of Software" propone una visión distinta y una serie de conceptos para hacer un diseño de sistemas mas enfocado y relacionado con el dominio, donde las reglas de negocio, el procesamiento de datos, la "carne" en si del software reside en los objetos que representan el dominio, los objetos del negocio. Una verdadera programación Orientada a Objetos.

En este post me voy a enfocar a explicar los conceptos de Entidad y Value Object que Eric maneja en su libro.

Una Entidad, Eric Evans la define como (según mi traducción al español):

"Hay una categoría de objetos los cuales tienen una identidad, la cual se mantiene igual durante los diferentes cambios del software. Para estos objetos, no son los valores de sus atributos los que importan,sino el hilo de continuidad e identidad, la cual cubre la vida del sistema y puede ir mas allá. Estos objetos son llamados Entidades."

Si buscamos en Wikipedia la definición de "identidad" encontramos algo como (de nuevo, según mi traducción al español):

"La identidad es lo que define a una entidad y la hace reconocible, en términos de poseer un conjunto de cualidades o características que distinguen a la entidad de otras entidades diferentes."

En términos de software y programación, la identidad es un valor que tiene el objeto #1 el cual es diferente del valor que tiene el objeto #2 y de esta forma los hacen distintos e identificables a cada uno de ellos. Esta identidad debe poder identificar al objeto durante su vida en el software no importando los diferentes cambios de estado que pueda tener este objeto.

Value Object es un patrón de diseño especificado por Martín Fowler en su libro "Patterns of Enterprise Application Architecture", y que después fue utilizado por la comunidad J2EE en los patrones base especificados en el libro "Core J2EE Patterns".

La definición de Value Object de Martín Folwer dice (según mi traducción al español):

"Un objeto simple y pequeño, como Moneda o un Rango de fechas, el cual su igualdad no esta dada en base a su identidad."

Un Value Object entonces no es identificado por su identidad si no por los valores que tengan sus atributos. Podría tener dos objetos fecha que tienen el mismo día, el mismo mes y el mismo año; estos objetos para mi son los mismos objetos, ¡es mas!, no tendría que tener dos instancias de estos objetos ya que solo estoy utilizando mas memoria y eso degradaría el desempeño del sistema. Eric recomienda ampliamente que los Value Objects puedan ser inmutables (una vez asignados los valores de sus atributos, no pueden cambiar) ya que de esta forma los Value Objects podría ser facilmente compartidos en el sistema ya que no tiene caso tener varias instancias de un Value Object que tiene los mismos valores y al ser inmutables no existe el riesgo de que un objeto deliveradamente cambie los valores de un Value Object mientras otro objeto lo esta usando.

Para dejar estos dos conceptos un poco mas claros supongamos que estamos haciendo un sistema para administrar nuestros contactos. Haciendo un análisis muy rápido de los conceptos involucrados en este sistema podríamos listar los siguientes:
  • Contacto.
  • Teléfono.
  • e-mail.
  • Dirección.
Teniendo estos conceptos, ¿cuales serian Entidades y cuales serian Value Objects?.

Un Contacto va a tener los atributos de nombre, apellido, fecha de nacimiento, una lista de teléfonos, otra lista de e-mail's y sus direcciones. Un Contacto seria una Entidad y no un Value Object, ¿porque?, por lo siguiente: yo podría llegar a conocer a dos personas que tengan el mismo nombre, el mismo apellido, la misma fecha de nacimiento y aun así ser dos personas distintas. También, podría darse el caso de que conozca a una persona de años y por alguna razón esta decida cambiarse el nombre ya que no le gusta (¡o cambiarse el sexo!), ¿tendría que tener a esta persona registrada dos veces en el sistema? no lo creo ya que se trata de la misma persona. De esto, un Contacto no esta definido por los valores de sus atributos; así que debemos darle una identidad a un Contacto, una forma única de identificarlo en el sistema que podría ser un ID generado de manera única o su NSS (Numero de Seguridad Social). Así, y con una identidad asignada, no importa que un Contacto cambie de nombre, o de sexo, o de dirección; siempre podre reconocer a este Contacto durante toda su vida en el sistema.

Por el otro lado, una Dirección seria un Value Object, ¿porque?, porque no pueden existir dos Direcciones que tengan el mismo país, la misma entidad federativa, el mismo código postal, la misma calle, el mismo numero exterior y el mismo numero interior. Es mas, una Dirección se puede compartir, ya que puedo tener dos Contactos que vivan en el mismo lugar.

Espero mi explicación sobre estos conceptos los haya dejado claros.

Referencias:

http://domaindrivendesign.org/
http://en.wikipedia.org/wiki/Domain-driven_design
http://www.martinfowler.com/bliki/ValueObject.html
http://www.martinfowler.com
http://en.wikipedia.org/wiki/Identity_(philosophy)