DDD Objetos de valor como atributos de clase.
14039 단어 developmententitiesphpddd
DDD Objetos de valor como atributos de clase.
En un poco de contexto, Domain Driven Design( DDD
) es una forma de desarrollar software en capas, dando Prioridad a la lo lógica del negocio(o dominio), unificando el lenguaje de전문 기술 de negocio con el lenguaje técnico en algo conocido 코모 Ubiquitous Language
y utilizando los principios SOLID
como el medio para lograr el producto final.
Dentro de la metodología de DDD los términos relacionados con los objetos más básicos del sistema son las entidades
와이 로스 objetos de valor
. Ambos conceptos hacen referencia a una clase Representativeativa de nuestro proyecto, regularmente un sustantivo en un caso de uso, por ejemplo, un usuario, una orden de compra, un artículo de inventario 등.
La diferencia entre las entidades
와이 로스 objetos de valor
es que estos últimos tienden a ser inmutables y mientras que una entidad
es un recurso que puede cambiar de estado, ser persistido y/o posteriormente eliminado.
Mientras estudiaba DDD me encontré con una implementación en la que los atributos de las clases pasaban de ser un tipo primitivo (por ejemplo, string o int) a un objeto de valor.
Para ejemplificarlo en detalle, supongamos que tenemos una clase Usuario
que tiene los atributos nombre
Y edad
:
# User.php
class Usuario
{
/** @var string */
private $nombre;
/** @var int */
private $edad;
public function __construct(float $nombre, float $edad)
{
$this->nombre = $nombre;
$this->edad = $edad;
}
}
Clase con objetos de valor como atributos
Primero que nada, se tenía una clase para Representativear el tipo de dato string
:
# StringValueObject.php
class StringValueObject
{
/** @var string */
protected $value;
public function __construct(string $value)
{
$this->value = $value;
}
public function getValue(): string
{
return $this->value;
}
public function toString(): string
{
return $this->getValue();
}
}
Postiormente se tenía una clase para Representativear el atributo name
델 오브제 Usuario
:
# NombreUsuario.php
class NombreUsuario extends StringValueObject
{
public function __construct(string $value)
{
parent:__construct($value);
}
}
Lo mismo sucedía para la edad, inicialmente una clase para Representativear el tipo de dato int
:
# IntValueObject.php
class IntValueObject
{
/** @var int */
protected $value;
public function __construct(int $value)
{
$this->value = $value;
}
public function getValue(): int
{
return $this->value;
}
public function toString(): string
{
return strval($this->getValue());
}
}
Después de una Representativeación del tipo int
, continúa una clase para Representativear el atributo edad
델 Usuario
:
# EdadUsuario.php
class EdadUsuario extends IntValueObject
{
public function __construct(int $value)
{
parent:__construct($value);
}
}
Finalmente se tenía la clase Usuario
queda de la siguiente manera:
# Usuario.php
class Usuario
{
/** @var NombreUsuario */
private $nombre;
/** @var EdadUsuario */
private $edad;
public function __construct(NombreUsuario $nombre, EdadUsuario $edad)
{
$this->nombre = $nombre;
$this->edad = $edad;
}
}
Mi primera reacción fue un notable WFT?
Después de detenerme a analizar el porqué de todo esto, entendí lo siguiente.
Delegar reglas de dominio a los objetos de valor
Primero que nada, al crear una clase para cada atributo, podemos delegar la validación a éstas clases, por ejemplo, en el caso del nombre, nunca aceptaríamos un string vacío, por lo que extenderíamos esa funcionalidad de la siguiente manera:
# NombreUsuario.php
class NombreUsuario extends StringValueObject
{
public function __construct(string $value)
{
$this->asegurarNombreNoVacio(string $value);
parent:__construct($value);
}
private function asegurarNombreNoVacio(string $value)
{
if ('' === $value) {
throw new \InvalidArgumentException('El nombre no puede estar vacío.');
}
}
}
En dónde, si el valor no es vacío en automático arroja una excepción, lo mismo aplica para las validaciones de la clase EdadUsuario
, en dónde la edad no puede ser menor a 0, quedando:
# EdadUsuario.php
class EdadUsuario extends IntValueObject
{
public function __construct(int $value)
{
parent:__construct($value);
}
private function asegurarEdadMinimaDe0($value)
{
if ($value < 0) {
throw new \InvalidArgumentException('La edad no puede ser menor a 0.');
}
}
}
Integridad en nuevas instancias
Al delegar las validaciones a unobjeto de valor
, cuando nosotros requiramos una instancia de Usuario
, no deberemos preocuparnos por la integridad, dado que todos los valores ingresados serían válidos o se detendrá la ejecución mostrando un error.
Código en un solo lugar
A parte de esto, nos brinda la facilidad de crear atributos compartidos entre clases y "módulos"(conocidos como sudominios
en DDD), por ejemplo, si el Usuario
tuviera alguna relación con alguna otra entidad
como lo puede ser Rol
, los atributos en formato de objeto de valor
utilizarán la misma cla, y por ende no necesitaremos duplicar código en todos aquellos recursos compartidos.
결론
DDD tiene bastantes conceptos interesantes, muchos de ellos parecen hacer el código muy complejo, pero a largo plazo, proporciona una manera muy escalable y mantenible de hacer código, ¿qué te parece la implementación de objetos de valor como atributos de clase?
Reference
이 문제에 관하여(DDD Objetos de valor como atributos de clase.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/javleds/ddd-objetos-de-valor-como-atributos-de-clase-1npa
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
# User.php
class Usuario
{
/** @var string */
private $nombre;
/** @var int */
private $edad;
public function __construct(float $nombre, float $edad)
{
$this->nombre = $nombre;
$this->edad = $edad;
}
}
# StringValueObject.php
class StringValueObject
{
/** @var string */
protected $value;
public function __construct(string $value)
{
$this->value = $value;
}
public function getValue(): string
{
return $this->value;
}
public function toString(): string
{
return $this->getValue();
}
}
# NombreUsuario.php
class NombreUsuario extends StringValueObject
{
public function __construct(string $value)
{
parent:__construct($value);
}
}
# IntValueObject.php
class IntValueObject
{
/** @var int */
protected $value;
public function __construct(int $value)
{
$this->value = $value;
}
public function getValue(): int
{
return $this->value;
}
public function toString(): string
{
return strval($this->getValue());
}
}
# EdadUsuario.php
class EdadUsuario extends IntValueObject
{
public function __construct(int $value)
{
parent:__construct($value);
}
}
# Usuario.php
class Usuario
{
/** @var NombreUsuario */
private $nombre;
/** @var EdadUsuario */
private $edad;
public function __construct(NombreUsuario $nombre, EdadUsuario $edad)
{
$this->nombre = $nombre;
$this->edad = $edad;
}
}
# NombreUsuario.php
class NombreUsuario extends StringValueObject
{
public function __construct(string $value)
{
$this->asegurarNombreNoVacio(string $value);
parent:__construct($value);
}
private function asegurarNombreNoVacio(string $value)
{
if ('' === $value) {
throw new \InvalidArgumentException('El nombre no puede estar vacío.');
}
}
}
# EdadUsuario.php
class EdadUsuario extends IntValueObject
{
public function __construct(int $value)
{
parent:__construct($value);
}
private function asegurarEdadMinimaDe0($value)
{
if ($value < 0) {
throw new \InvalidArgumentException('La edad no puede ser menor a 0.');
}
}
}
Reference
이 문제에 관하여(DDD Objetos de valor como atributos de clase.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/javleds/ddd-objetos-de-valor-como-atributos-de-clase-1npa텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)