13

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
Susantha7
  • 898
  • 1
  • 20
  • 38
  • "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" - it's up to you how you structure the code base. For me it would make more sense to have a directory per bounded context (e.g Blog, User) and within this directory the concrete classes reside (User, UserRepository, ...). It's a matter of taste, but I prefer package by feature and not by layer.. – Andreas Aumayr Mar 15 '17 at 07:57
  • MVC is more of a UI architecture. It does not fit well in DDD. – Constantin Galbenu Mar 15 '17 at 20:03
  • Do not compare DDD and MVC because it's not about how do you organise your folder structures. DDD is almost the WAY you design your application. DDD contains various strategical and tactical patterns. MVC is just one tactical pattern – Andrey Degtyaruk Mar 22 '17 at 20:18

5 Answers5

8

in mvc the model is a layer and it's contain all the domain business logic.

I doubt MVC pattern itself declares something special about the Domain. It operates model as a bag of properties and doesn't care how it was created and how it guards its invariants.

At the same time Onion architecture states that it's important to isolate Domain out of Application Service (which MVC Framework is). So I like to place Domain layer which contains Entities, Value objects, Domain events and Aggregates to a separate module or a top-level folder.

enter image description here

One more reason for placing Domain separately from MVC stuff is that it will allow you easier manage multiple bounded contexts, because each context needs its own module/folder.

I sugget you to check out this ASP MVC project structure. It was designed by well-known DDD expert. Besides domain, please take a look at how MVC part is organized. It exploits feature slice approach which is getting more and more popular these days and I find it extremely useful.

Zharro
  • 819
  • 1
  • 11
  • 23
3

Although I'm quite new to the world of DDD, in the process of gradually migrating an application I was working on to a more DDD-oriented structure I also confronted the question of directory structure. Piecing together the information I was able to find which wasn't entirely conceptual I came up with the following simplified directory structure, (which exists within a CRUD-oriented Laravel application), that has served me well enough:

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

Addressing your specific concerns, repository interfaces and entities were placed within Domain folders underneath each separable component of the application (e.g. - User). Additionally, this is where I placed any Domain events and exceptions. Repository implementations were placed under each Infrastructure folder. Application services are placed within a Services directory under Application directories.

Leaving aside the hybrid nature of my own application (I'm using ORM-reliant DAO's/Entities, transaction scripts, and avoiding Value Objects just to name a few diversions), this may still help serve as a rough idea of a potential DDD directory structure within an MVC app.

alaric
  • 987
  • 5
  • 10
1

I am agree with @Zharro's suggestion.

Good structure is like below:

  • View (Contains only view part like twig, html and assets)
  • Core (Controller, Form, Listeners, Helpers)
  • BusinessLogic (Include services)
  • Entity (Entity, Commands, Validator)

1) View part access only CoreBundle and does not change behaviour of database.

2) Core part access BuisnessLogic and Entity

3) BuisnessLogic part access only Entity

4) Entity part access only database.

Bhavin Nakrani
  • 442
  • 3
  • 12
1

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.
Sylvain Lecoy
  • 947
  • 6
  • 15
0

I would consider the Model in MVC to be a combination of ViewModels and Commands. Incoming requests are mapped to commands that would get dispatched to a "write" layer that retrieves the appropriate aggregate and calls the appropriate method on it, then commits the transaction.

ViewModels exist solely to carry data in a presentation-ready format for the user interface. You can have a very simple "read" layer that queries database views or tables and returns the results to the client. This will allow you to have a domain model that does not expose all of its state via getters and setters.

pnschofield
  • 877
  • 1
  • 6
  • 16
  • I agree with what @Zharro has to say about separating your domain model from your application. Ideally, the domain model would be in a separate package so that it can be shared and used by multiple applications. – pnschofield Mar 22 '17 at 18:42