Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

implement DDD in MVC Frameworks - PHP

in mvc the model is a layer and it's contain all the domain business logic.
in domain driven design business logic can be divide into various building blocks like.

in Domain Driven Design domain model is.

A domain model is a system of abstractions that describes selected aspects of a sphere of knowledge, influence or activity (a domain). The model can then be used to solve problems related to that domain

developer has read Domain Driven Design, or is using Doctrine2 or Hibernate, usually have a better focus on the domain model in DDD.in mvc frameworks model layer is overlap with domain model in DDD.it means we can implement domain model in model folder in mvc frameworks

such a implementations is shown below.shows how model folder is structure

   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


  • i want to know is my first assumption (can implement domain model in model folder in mvc frameworks)is correct ?
  • is it correct design that the all the building blocks in DDD implement in model folder (as shown in above) such as entities,services,repositories
  • or any other suggestions that you have regarding this implementation.
  • if this is wrong what is the correct way of implementing building blocks of DDD such as entities,services,repositories in mvc frameworks
like image 293
Susantha7 Avatar asked Mar 15 '17 07:03

Susantha7


People also ask

Is DDD an MVC?

Domain-driven design separates the model layer “M” of MVC into an application, domain and infrastructure layer. The infrastructure layer is used to retrieve and store data. The domain layer is where the business knowledge or expertise is.

What is DDD in PHP?

DDD is about sharing the language between the code and the business domain. Another value of DDD: the code has value at runtime AND at rest. The code is self-documenting a business process, acting as knowledge center for any human interacting with it.

What is DDD in laravel?

Domain-Driven Design (DDD) stands for a unified approach to software design that provides a precise structure and set of rules that make software design decisions easier and more suitable for complex domains (business logic).

What is domain in DDD principle?

Domain-Driven Design(DDD) is a collection of principles and patterns that help developers craft elegant object systems. Properly applied it can lead to software abstractions called domain models. These models encapsulate complex business logic, closing the gap between business reality and code.


1 Answers

Your first assumption is not correct, MVC does not really fit with DDD, a better approach would be to use the CQRS pattern.

Your second assumption is also not correct, buildings blocks are not all in the domain model folder, actually, here is a good structure for your project:

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/
        ...

That way you can keep a pseudo MVC, but with the difference that View and Controller are in Interfaces package, and the Rich Model is in the domain/model package. You can only manipulate the model through Application services, and querying the model through Query services. Query services provides you fast access to model representation, and commands are sent to Application services to behave as controllers.

Note the CommentAuthor class could be a Value Object, not containing the user ID of database but a unique username. Since the User aggregate root is from another package: which makes sense from a domain PointOfView. We could call it an identity (or username). This would be ideally mapped to a unique column of the User table, but would be an indexed value of the Comment table.

Another option would be to use the User in the Blog package as part of the same concept which is a blog but DDD does not recommend this approach. Actually it would recommand you to put the Identity and Access in a separate bounded context, but I guess in the context of the application you are writing mapping the user as part of a Comment could be ok.

In the infrastructure layer, you define your persistence provider, that way, the day you want to switch to Doctrine, only the implementation in this package must change.

The application layer is responsible to manage security, span transactionnal context, and log high level events.

I can provide you more insight about the inners of classes if you need some clarification. Also this might requires some infrastructure or a support framework to get it working, i'm thinking at:

  • dependency injection,
  • event dispatcher available in entitites,
  • some kind of event bus if you plan to consume these events.
like image 155
Sylvain Lecoy Avatar answered Oct 27 '22 01:10

Sylvain Lecoy