Value Objects

En DDD (domain driven design) los value objects son objetos simples que cuantifican, miden o describen algo que pertenece a nuestro dominio. Representan un valor y es su valor lo que importa y lo que los diferencia de otros value objects.

Hay dos aspectos a tener en cuenta para entenderlo mejor:

  1. Como dice Ward Cunningham, es una medida o una descripción de algo.
  2. Su identidad se define a través de su estado y no usando un campo identificador único. Así que, como dice Martin Fowler, dos value objects son iguales si sus atributos contienen los mismos valores. Deben ser inmutables.

Algunos ejemplos de value objects pueden ser:

  • Una fecha
  • Dinero
  • Un nombre
  • Una dirección
  • Una cantidad

Un ejemplo concreto

Por ejemplo, en una receta de cocina, podríamos tener un value object que representara la cantidad “250 gramos”. En realidad esa instancia concreta de la cantidad “250 gramos” no importa demasiado en si misma, si no es a través de su valor. En tanto que objeto inmutable, sea esta u otra instancia, lo importante es el valor que tiene. Será igual a otra con el valor “250 gramos”.

Si necesitáramos representar el valor “1 kilogramo”, aunque también se trata de una cantidad, en lugar de modificar la instancia previa, crearemos una nueva.

Una ventaja obvia de conceptualizar estas descripciones bajo la forma de value objects, es que todo el comportamiento relativo a ellos puede ser implementado dentro de esas clases, por ejemplo una validación. De esta forma tenemos otra ventaja: luchamos contra el anti-pattern de los modelos de dominio anémicos.

Show me the code

Me gustaría traducir en código el ejemplo de la cantidad para los ingredientes de una receta. Por ejemplo “250 gramos” podría ser resuelto con una clase que guarde el tipo de medida (gramos, kilos, mililitros…) y otra que une este concepto a una cantidad (1, 250, 3.5).

Ambas son value objects, en este caso miden la cantidad necesaria de un ingrediente en una receta.

class Measure
{

    private $name;

    public function __construct($name)
    {
        $this->setName($name);
    }

    private function setName($name)
    {
        //implements some validation
        $this->name = $name;
    }

    public function name()
    {
        return $this->name;
    }
}
 

class Quantity
{

    private $amount;
    private $measure;

    public function __construct($amount, Measure $measure)
    {
        $this->setAmount($amount);
        $this->setMeasure($measure);
    }

    private function setAmount($amount)
    {
        $this->amount = floatval($amount);
    }

    private function setMeasure(Measure $measure)
    {
        $this->measure = $measure;
    }

    public function amount()
    {
        return $this->amount;
    }

    public function Measure()
    {
        return $this->measure;
    }
}

Domain Driven Design

Domain Driven Design book by Eric Evans

 

No sabia que cuando en la oficina he dicho “Al final de lo que se trata es de que el cliente sea feliz y de que nosotros los programadores también lo seamos” lo que estoy haciendo es promover Domain Driven Design.

Microservices, Self contained systems, Domain driven design y otros en el fondo lo que pretenden es que todos los actores de un dominio particular extremen su rendimiento y felicidad. La empresa que necesita una solución de software de calidad obtendrá un beneficio a medio plazo. Los programadores diseñarán paso a paso una aplicación en la que pueden confiar y los managers dejarán de arrancarse el pelo.

Divide y vencerás

Cuando observo un poco mas de cerca estas metodologías tengo la impresión de que todas se parecen demasiado, aun con sus grandes diferencias. Es como si todas ellas emanaran de la misma fuente: La necesidad de separar las responsabilidades a todos los niveles.

El principio SR (Single responsability) impregna todo buen comienzo en los cuentos de software. Al dedicar tiempo a definir:

  • el modelo de tu dominio
  • los objetos que lo habitan
  • sus necesidades
  • los datos que circulan y su forma de transmitirse y relacionarse
  • los servicios y la infraestructura que existe en el mundo representado e inmaterial del software

lo que haces es una vez más dividir.

Cuando la aplicaciones comenzaron a crecer exponencialmente y los pioneros de la profesión notaban que perdían el control y se les ponían de corbata, se hicieron necesarias normas que ayudaran a organizar sistemas complejos.

Hablemos

Al parecer había un abismo entre los equipos que desarrollaban el software y aquellos que llevan a cabo la “principal” actividad empresarial. Vamos, lo que todo el mundo identificaría como la fuente de beneficios. ¿Y el software entonces, qué es?. Lo que promueve el DDD en los equipos de trabajo es llegar a desarrollar un idioma conjunto, usado tanto por los expertos de dominio como por los desarrolladores. Esto quiere decir muchas cosas, por ejemplo tu variable $hash2 que solo tu sabes lo que es se convertirá en $bookings. Como ves la variable $bookings es significativa tanto para los expertos de dominio, como para los desarrolladores de software. Para conseguir eso muchas horas de común conversación habrán tenido lugar en la sala de reuniones. Cuando todo el mundo comparte los mismos conceptos, la misma semántica de dominio: hemos alcanzado el nirvana del DDD y nuestro software debe reflejarlo.

De qué trata

De modelar tu software siguiendo una hermenéutica de dominio. Lo cual quiere decir que una vez conocemos el mundo que debe representar nuestro software, resolverlo usando DDD, nos provee un marco en el que trabajar con garantías de que ese mundo no se convertirá en algo incomprensible, monolítico e imposible de verificar: Spaguetti code.

Crear sistemas complejos basados en software de alta calidad. DDD no es arquitectura. Descubrir poco a poco el dominio, interactuar con los expertos, generar poco a poco el Ubiquitous language común a todos, es aportar valor y conocimiento al negocio.

Show me the money!

 

Colofón

Como introducción de un novato en DDD, no deberías fiarte en absoluto de lo que digo sino leer el famoso libro de Eric Evans. Los sistemas complejos necesitan formas de construirse, de organizarse e integrarse, así como filosofías de trabajo y formas de entender la profesión. Veo un poco de todo eso en el DDD.

DDD provee un análisis sintáctico para la arquitectura de software.

 

Desde un punto de vista más técnico, para aplicar DDD a tu aplicación, además de mejorar la comunicación con el cliente y ser experto del dominio, hay que saber utilizar Domain Services, Value Objects, Modules, Aggregates, Entities, Domain Events, Factories o Repositories.