mejor - php frameworks
implementar DDD en MVC Frameworks-PHP (5)
en mvc, el modelo es una capa y contiene toda la lógica comercial del dominio.
Dudo que el patrón MVC declare algo especial sobre el Dominio. Opera el modelo como una bolsa de propiedades y no le importa cómo se creó y cómo protege sus invariantes.
Al mismo tiempo, la arquitectura Onion afirma que es importante aislar el dominio fuera del servicio de aplicaciones (que es MVC Framework). Así que me gusta colocar la capa de dominio que contiene entidades , objetos de valor , eventos de dominio y agregados en un módulo separado o una carpeta de nivel superior.
Una razón más para colocar Domain de forma separada de MVC es que le permitirá administrar más fácilmente múltiples contextos delimitados , ya que cada contexto necesita su propio módulo / carpeta.
Sugiero que revises esta estructura de proyecto de ASP MVC . Fue diseñado por un conocido experto en DDD. Además del dominio, mira cómo está organizada la parte MVC. Explota el enfoque de sectores de función que cada vez es más popular y me resulta extremadamente útil.
en mvc, el modelo es una capa y contiene toda la lógica comercial del dominio.
en lógica de negocio de diseño impulsado por dominio se puede dividir en varios bloques de construcción como.
en el modelo de dominio de diseño impulsado por el dominio es.
Un modelo de dominio es un sistema de abstracciones que describe aspectos seleccionados de una esfera de conocimiento, influencia o actividad (un dominio). El modelo se puede usar para resolver problemas relacionados con ese dominio
El desarrollador ha leído Domain Driven Design, o está usando Doctrine2 o Hibernate, por lo general tiene un mejor enfoque en el modelo de dominio en DDD. En mvc frameworks, la capa del modelo se superpone con el modelo de dominio en DDD. Esto significa que podemos implementar un modelo de dominio en la carpeta del modelo. marcos mvc
tales implementaciones se muestran a continuación. muestra cómo la carpeta de modelo es estructura
Model(this can model or domain)
|
|----Entities
| |---BlogPost.php
| |---Comment.php
| |---User.php
|
|----Repositories
| |---BlogPostRepository.php
| |---CommentRepository.php
| |---UserRepository.php
|
|----Services
| |---UserService.php
|
|----factories
| |---userfactory.php
|
|----dataMappers
| |---userDataMapper.php // this inherit from Eloquent model
|
|----ValueObject
- Quiero saber si mi primera suposición (¿puede implementar un modelo de dominio en la carpeta de modelos en mvc frameworks) es correcta?
- ¿Es correcto el diseño que implementan todos los componentes en DDD en la carpeta de modelos (como se muestra arriba) como entidades, servicios, repositorios?
- o cualquier otra sugerencia que tenga con respecto a esta implementación.
- Si esto es incorrecto, ¿cuál es la forma correcta de implementar bloques de construcción de DDD, como entidades, servicios, repositorios en marcos mvc?
Aunque soy bastante nuevo en el mundo de DDD, en el proceso de migrar gradualmente una aplicación en la que estaba trabajando a una estructura más orientada a DDD, también me enfrenté a la cuestión de la estructura de directorios. Recopilando la información que pude encontrar que no era del todo conceptual, se me ocurrió la siguiente estructura simplificada de directorios (que existe dentro de una aplicación Laravel orientada a CRUD), que me ha servido bastante bien:
app/
ProjectName/
Core/
Application/
Domain/
Infrastructure/
User/
Application/
Services/
CreateUserService.php
FindUserService.php
UpdateUserService.php
Domain/
Role.php
RoleDAO.php
User.php
UserDAO.php
UserNotCreated.php
UserNotFound.php
UserNotUpdated.php
UserWasCreated.php
UserWasUpdated.php
Infrastructure/
EloquentRoleDAO.php
EloquentUserDAO.php
Al abordar sus inquietudes específicas, las interfaces y entidades de depósito se colocaron dentro de las carpetas de Dominio debajo de cada componente separable de la aplicación (por ejemplo, el usuario). Además, aquí es donde coloqué cualquier evento de dominio y excepciones. Las implementaciones de repositorio se colocaron debajo de cada carpeta de Infraestructura. Los servicios de aplicaciones se colocan dentro de un directorio de Servicios en los directorios de la Aplicación.
Dejando de lado la naturaleza híbrida de mi propia aplicación (estoy usando ORD / Entidades dependientes de ORM, secuencias de comandos de transacción y evitando objetos de valor solo por nombrar algunas diversiones), esto aún puede servir como una idea aproximada de un posible directorio de DDD estructura dentro de una aplicación MVC.
Considero que el Modelo en MVC es una combinación de ViewModels y Comandos. Las solicitudes entrantes se asignan a los comandos que se envían a una capa de "escritura" que recupera el agregado apropiado y llama al método apropiado sobre él, y luego confirma la transacción.
ViewModels existe únicamente para transportar datos en un formato listo para la presentación para la interfaz de usuario. Puede tener una capa de "lectura" muy simple que consulta las vistas o tablas de la base de datos y devuelve los resultados al cliente. Esto le permitirá tener un modelo de dominio que no exponga todo su estado a través de getters y setters.
Estoy de acuerdo con la sugerencia de @Zharro.
Buena estructura es como a continuación:
- Ver (contiene solo la parte de vista como ramita, html y activos)
- Núcleo (controlador, forma, oyentes, ayudantes)
- BusinessLogic (Incluir servicios)
- Entidad (Entidad, Comandos, Validador)
1) Ver el acceso parcial solo CoreBundle y no cambia el comportamiento de la base de datos.
2) Acceso de parte de núcleo BuisnessLogic y entidad
3) BuisnessLogic solo acceso a la parte Entidad
4) Base de datos solo de acceso a parte de entidad.
Su primera suposición es incorrecta, MVC realmente no encaja con DDD, un mejor enfoque sería usar el patrón CQRS.
Su segunda suposición tampoco es correcta, los bloques de edificios no están todos en la carpeta del modelo de dominio, de hecho, aquí hay una buena estructura para su proyecto:
ProjectName/
Application/
Blog/
Command/
CommentToBlogPostCommand.php
ChangeCommentContent.php
DescribeBlogPostCommand.php
NewBlogPostCommand.php
...
Data/
BlogPostData.php
BlogPostCommentsData.php (POPO containing BlogPost infos and the comments array)
CommentData.php (Single comment infos)
BlogPostApplicationService.php
BlogPostQueryService.php
CommentApplicationService.php
CommentQueryService.php
Identity/
Command/
AuthenticateUserCommand.php
ChangeEmailAddressCommand.php
ChangeUserPasswordCommand.php
ChangeUserPersonalNameCommand.php
DefineUserEnablementCommand.php
RegisterUserCommand.php
UserApplicationService.php (this defines the actions that can be done by your application related to user domain, injected in presentation layer responding to user events)
UserQueryService.php (this will usually be injected in your presentation layer)
Domain/
Model/
Blog/
BlogPost.php
BlogPostClosed.php (this could be a list of possible events)
BlogPostDescriptionChanged.php
BlogPostModeratorChanged.php
BlogPostReopened.php
BlogPostStarted.php
BlogPostRepository.php (interface)
Comment.php (this is an Entity, or Aggregate Root)
CommentContentAltered.php (this could be an event)
CommentAuthor.php (this could be a ValueObject, containing the username)
CommentRepository.php (interface)
CommentedToBlogPost.php (this could be another event when adding a comment to a blogpost)
...
Identity/
ContactInformation.php (VO or Person)
Enablement.php (VO of User)
EmailAddress.php (VO of ContactInformation)
FullName.php (VO or Person)
Person.php (ValueObject of User)
User.php (constructor visibility might be package-protected)
UserFactory.php
UserRepository.php (this is an interface)
UserService.php (this is a domain service)
Infrastructure/
Persistence/
LavarelBlogPostRepository.php (this implements BlogPostRepository)
LavarelCommentRepository.php (this implements CommentRepository)
LavarelUserRepository.php (this implements UserRepository)
Interfaces/
...
De esta forma puede mantener un pseudo MVC, pero con la diferencia de que View y Controller están en paquete de Interfaces, y Rich Model está en el paquete de dominio / modelo. Solo puede manipular el modelo a través de servicios de aplicación y consultar el modelo a través de servicios de consulta. Los servicios de consulta le brindan acceso rápido a la representación del modelo y los comandos se envían a los servicios de la aplicación para que se comporten como controladores.
Tenga en cuenta que la clase CommentAuthor podría ser un objeto de valor, que no contiene el ID de usuario de la base de datos, sino un nombre de usuario único. Dado que la raíz del agregado del usuario es de otro paquete: lo que tiene sentido desde un dominio PointOfView. Podríamos llamarlo una identidad (o nombre de usuario). Esto se correlacionaría idealmente con una columna única de la tabla de usuarios, pero sería un valor indexado de la tabla de comentarios.
Otra opción sería usar el usuario en el paquete Blog como parte del mismo concepto que es un blog, pero DDD no recomienda este enfoque. En realidad, te recomendaría poner la Identidad y el Acceso en un contexto delimitado separado, pero supongo que en el contexto de la aplicación que estás escribiendo, mapear al usuario como parte de un Comentario podría estar bien.
En la capa de infraestructura, defina su proveedor de persistencia, de ese modo, el día que desee cambiar a Doctrine, solo la implementación en este paquete debe cambiar.
La capa de aplicación es responsable de administrar la seguridad, abarcar el contexto transaccional y registrar eventos de alto nivel.
Puedo proporcionarle más información sobre los internos de las clases si necesita alguna aclaración. Además, esto podría requerir alguna infraestructura o un marco de apoyo para que funcione, estoy pensando en:
- inyección de dependencia,
- despachador de eventos disponible en las entidades,
- algún tipo de bus de eventos si planea consumir estos eventos.