¿Dónde trazamos la línea entre la delegación y la encapsulación de la lógica empresarial? Me parece que cuanto más delegamos, más anémicos nos volvemos. Sin embargo, la delegación también promueve la reutilización y el director DRY. Entonces, ¿qué es apropiado delegar y qué debe permanecer en nuestros modelos de dominio?
Tome las siguientes preocupaciones como ejemplos:
Autorización . ¿Debería el objeto de dominio ser responsable de mantener sus reglas de control de acceso (como una propiedad CanEdit) o debería delegarse en otro componente / servicio exclusivamente responsable de administrar el acceso, por ejemplo, IAuthorizationService.CanEdit (objeto)? ¿O debería ser una combinación de los dos? ¿Quizás el objeto de dominio tiene una propiedad CanEdit que delega a un IAuthorizationService interno para realizar el trabajo real?
Validación . La misma discusión que la anterior se relaciona con la validación. ¿Quién mantiene las reglas y quién es responsable de evaluarlas? Por un lado, el estado del objeto debe pertenecer a ese objeto y la validez es un estado, pero no queremos reescribir el código utilizado para evaluar las reglas para cada objeto de dominio. Nosotros podríamos utilizar la herencia en este caso ...
Creación de objetos . Clase de fábrica versus métodos de fábrica versus 'novedad' en una instancia. Si utilizamos una clase de fábrica separada, podemos aislar y encapsular la lógica de creación, pero a expensas de abrir el estado de nuestro objeto a la fábrica. Esto se puede administrar si nuestra capa de dominio está en un ensamblaje separado al exponer un constructor interno utilizado por la fábrica, pero esto se convierte en un problema si hay múltiples patrones de creación. Y, si todo lo que hace la fábrica es llamar al constructor correcto, ¿cuál es el punto de tener la fábrica?
Los métodos de fábrica en la clase eliminan el problema de abrir el estado interno del objeto, pero como son estáticos, no podemos romper las dependencias mediante la inyección de una interfaz de fábrica como podemos hacerlo con una clase de fábrica separada.
Persistencia . Se podría argumentar que si nuestro objeto de dominio va a exponer CanEdit mientras se delega la responsabilidad de realizar la verificación de autorización a otra parte (IAuthorizationService), ¿por qué no tener un método Save en nuestro objeto de dominio que haga lo mismo? Esto nos permitiría evaluar el estado interno del objeto para determinar si la operación se puede realizar sin romper la encapsulación. Por supuesto, requiere que inyectemos la instancia del repositorio en nuestro objeto de dominio, lo que me huele un poco, así que, ¿generamos un evento de dominio y permitimos que un controlador realice la operación de persistencia?
¿Ves a dónde voy con esto?
Rockford Lhotka tiene una gran discusión sobre sus razones para seguir la ruta de la Clase a Cargo para su marco CSLA y tengo un poco de historia con ese marco y puedo ver su idea de los objetos de negocios paralelos a los objetos de dominio de muchas maneras. Pero tratando de ser más adherente a los buenos ideales DDD, me pregunto cuándo la colaboración se vuelve demasiado.
Si termino con un IAuthorizationService, IValidator, IFactory e IRepository para mi raíz agregada, ¿qué queda? ¿Es suficiente tener un método de publicación que cambie el estado del objeto de borrador a publicado para considerar que la clase es un objeto de dominio no anémico?
¿Tus pensamientos?