2012-02-06 13 views
5

Estoy interesado en DDD (Diseño dirigido por el dominio) en los últimos días, pero no puedo entender las responsabilidades de quién crea y valida las entidades. Voy a romper estas preguntas para cubrir diferentes escenarios.DDD - Responsabilidad de creación y validación de entidades

  1. Entidad regular (Posiblemente con objeto de valor). Como ejemplo, tomemos un usuario identificado por correo electrónico. Tengo un UserFactory que recibe una matriz de datos (posiblemente desde el formulario POST) y me devuelve una nueva UserEntity. ¿Debería la fábrica validar la integridad de los datos (por ejemplo, una cadena dada como Correo electrónico es un correo electrónico real, contraseñas en el campo de contraseña 1 y coincidencia de campo 2, etc.)? ¿Debería la fábrica validar que ya no existe ese usuario (no queremos registrar dos usuarios con el mismo correo electrónico)? En caso afirmativo, ¿debería hacerlo él mismo o usar el UserRepository?

  2. Entidad agregada. Supongamos que tenemos una entidad Post y entidades de Comentarios. Quiero obtener la publicación 12 con todos sus comentarios, así que hago algo como

    $ post = $ postRepository-> getById (12);

¿Cómo se debe implementar getById? de esta manera:

public function getById($id) { 
    $postData = $this->magicFetchFromDB($id); 
    $comments = (new CommentRepository())->getForPost(12); 
    return new PostEntity($postData, $comments); 
} 

O tal vez el cargo responsable de la creación perezosa sus comentarios, algo así como:

class PostEntity { 
    public function getComments() { 
     if(is_null($this->_comments)) $this->_comments = (new CommentRepository())->getForPost($this->_id); 
     return $this->_comments; 
    } 
} 

? Estoy muy perdido aquí y no hay suficiente información con ejemplos de DDD en PHP, ¡así que cualquier ayuda será apreciada!

Muchas gracias, skwee.

Respuesta

4
  • La fábrica debe solamente se preocupan por la creación de entidades. Personalmente prefiero poner validación tanto en mis puntos de vista como en la capa de modelo. Usaría alguna biblioteca como el complemento de validación de jQuery para hacer alguna validación esencial en el lado del cliente (como verificar si los campos obligatorios tienen datos). Y luego haga la validación "hardcore" en el modelo. hago esto es mediante el uso de una clase abstracta sencilla BaseEntity la que todas las entidades se extienden, y desde que pidió un ejemplo, aquí está:

    abstract class BaseEntity { 
        public function isValid(); 
    }   
    
    class MyEntity extends BaseEntity { 
        public function isValid() { 
         //actual validation goes here 
        } 
    } 
    

    También se puede hacer uso de una clase auxiliar estática con un poco de validación básica métodos:

    class ValidationHelper { 
        public static function isValidPhonenumber($value) { 
         //check valid phonenumber, using a regex maybe 
        } 
    
        public static function isAlphanumeric($value) { 
         //check for letters and numbers only 
        } 
    } 
    

    Muchos argumentar en contra de los métodos estáticos, ya que pueden romper las pruebas de unidad, pero en este caso son bastante básico y no tienen dependencias externas, lo que los hace "más seguro".

  • Cuando se trata de verificar entidades ya existentes, puede hacer esto consultando su base de datos para ver si la entidad ya está allí antes de agregar/actualizar, o (así es como me gusta hacerlo) podría agregar un unique indexe las columnas que no pueden repetirse en el DB, y luego envuelva las consultas de creación o actualización en un bloque try-catch (la consulta arrojará una violación de restricción única, si dos usuarios tienen el mismo correo electrónico, por ejemplo) y luego mostrar el mensaje de error correcto

  • En su última pregunta, todo se reduce a una cuestión de preferencia. Si su base de datos obtendrá un millón de visitas en 1 minuto, entonces probablemente sea mejor usar carga lenta para evitar obtener datos innecesarios hasta que sea necesario. Pero si su base de datos es relativamente pequeña, puede utilizar perfectamente cargas ansiosas sin sacrificar demasiado rendimiento. Nuevamente, esta es una cuestión de preferencia personal.

espero que algo de esto divague tenga sentido, ¡salud!

+0

¡Gracias por tu comentario! A) No estoy seguro acerca de poner validación en la entidad. ¿Consideraría validar el captcha como parte de la lógica comercial? ¿Y qué pasa si tengo el panel de administración para agregar usuarios manualmente sin la necesidad de captcha? B) Sí, puedo, pero la pregunta es ¿de quién es la responsabilidad? Capa de validación? ¿Fábrica? ¿Repositorio? C) Bien, pero ¿y si tengo un Usuario que tiene publicaciones que tienen comentarios, será inteligente cargar todos estos datos para mostrar la página del perfil del usuario? –

+1

a) Depende de sus necesidades realmente, he encontrado que es "más fácil" tener validación en la propia entidad usando clases de ayuda. pero agregar una capa adicional de validación está perfectamente bien. b) diría que es la responsabilidad de la capa de validación. si dos cuentas no pueden tener el mismo número e intenta agregar una con un número que ya existe, eso significa que la entidad es ** inválida **, o al menos eso es lo que pienso. – jere

+1

c) esto también depende de lo que desee. si va a mostrar toda esa información de una vez en la página de perfil, entonces sí, cargue toda la información en una sola llamada. pero si muestra, digamos, solo las publicaciones, y cuando hace clic en una muestra los comentarios, sería mejor cargar los comentarios en ese momento, tal vez usando ajax – jere

1

La mejor y más sencilla forma de hacerlo es usar Doctrine2. Tal vez las primeras horas sean difíciles, pero una vez que dominas Doctrine2, todas esas relaciones y agregados son pan comido.

Puede encontrar mucha información sobre PHP & DDD o Doctrine2 en http://giorgiosironi.blogspot.com/ o simplemente buscando en Google.

RE: Validación: considerando el Principio de Responsabilidad Individual utilizamos objetos de Validación. La validación puede ser compleja y puede requerir otros repositorios o entidades por lo que es mejor mantenerla aparte de la entidad real, sujeto de la validación para evitar la creación de objetos inflados. Puede usar el patrón de diseño de visitante o especificación.

Aquí hay muchas otras publicaciones relacionadas con esos temas: intente utilizar las palabras clave anteriores.

+0

Usé la doctrina en aquel entonces, realmente no me gustó, era grande y pesada. Sin embargo, fue pre Doctrine2, podría darle una oportunidad a Doctrine. Sin embargo, todavía estoy más interesado en la forma correcta de hacer las cosas que en encontrar una solución preparada. En cuanto a la validación, ¡gracias por traernos el SRP! Me olvidé de todo y no estaba seguro si debería insertar otra capa de Validación, ahora estoy seguro de que necesito :) –

+0

Doctrine se basó en el patrón Active Record, Doctrine2 es exactamente lo que necesita para una implementación más fácil de DDD. Como escribí en otra publicación similar, las soluciones caseras generalmente terminan como pesadilla de mantenimiento y Aggregate Roots se vuelven muy manuales. Por lo general, cada AR se realiza de forma diferente en función de qué desarrollador lo hizo. He estado allí, créeme, no quieres ir por ese camino ... –

+0

Tengo el síndrome de "reinventar la rueda". Si me pidieran que implementara DDD en mi lugar de trabajo con un calendario apretado, probablemente iría con Doctrine. Como mi pregunta surgió de mi proyecto personal, en el que no tengo fechas límite estrictas, prefiero aprender tanto como sea posible implementando esto. Tengo una buena solución ATM, pero me temo que se romperá tan pronto como trate de complicarla, así que estoy considerando Doctrine. Además, AFAIK Doctrine no es compatible con el almacenamiento no DB (es decir, bases de datos basadas en archivos o no SQL), esto podría ser un problema para el futuro (estoy seguro de que escribir un controlador no es un problema). –

Cuestiones relacionadas