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)