At present we have 2 PHP applications which share absolutely no code, but share a common database. One app is the timesheet application for administrators, the other is the timesheet applications employees log their time against projects. We are proposing a complete rebuild of the application using Spring Boot, Spring Data Jpa, Hibernate, Java8. We want to keep the applications separate as business may want to deploy and make changes to them independently, and they also present and take different data so it doesn't make sense for them to share the same models and API anyway.

The applications doesn't have a lot of complex business rules yet, the system is half data entry, and half reporting. However over time there is more functionality that is being handled manually that we want to being into the system. As such I would like to borrow some of the ideas of DDD and CQRS into the design.

My proposal is a multi module Maven solution

-- Timesheet (parent module)
  -- timesheet-core
    -- domain services
    -- repositories
    -- domain models / jpa entities
    -- other common logic and classes
  -- timesheet-web-admin
    -- controllers / rest endpoints
    -- services (will query from here for read operations, writes go through repositories)
    -- DTOs (used to move data between client and other layers)
  -- timesheet-employee-admin
    -- controllers / rest endpoints
    -- services (will query from here for read operations, writes go through repositories)
    -- DTOs (used to move data between client and other layers)

I'm not one who believes in strictly following patterns like a doctrine / religion. I think DDD and CQRS ideas and patterns might be beneficial though. We have roughly 100 - 120 people using this system so I'm not sure if event sourcing and having separate databases is really necessary.

Does this design / architecture at least make sense from a high level or am I making a terrible mistake trying to bring DDD into the fold? My idea is JPA / Repositories will handle all write operations, but the appliation services will handle reads and returning the data in DTO objects.

enter image description here

  • I believe, just like @DavidPacker, that CQRS works. I recommend that you take a look at the hexagonal architecture that works very well with DDD and CQRS. Also, you could take a look at microservices as they permit to work independently at separate domains and promote loose coupling between them. – Constantin Galbenu Mar 2 '17 at 18:35
  • @ConstantinGALBENU We looked at the Microservice approach but we were worried about data consistency, although I suppose all the microservices could share the same database. If they had separate databases there would be another layer of complexity syncing data between the services – greyfox Mar 3 '17 at 13:48
  • no, the microservices must not share the same database, it would be against the main purpose of loose coopling – Constantin Galbenu Mar 3 '17 at 14:10
  • Would something like JMS be sufficient for communicating between micro services? Say information is created in Service 1 that Service 2 needs to know about to persist and update its database. Could you just fire a JMS message to ActiveMQ or something like that? – greyfox Mar 3 '17 at 17:11

I am currently working on an application that also does some time reporting. It has never appeared to be a "just data entry and reporting" application.

DDD or not is not what you decide by looking at the solution space alone. You should get yourself out of the developers comfort zone and drag yourself to the problem space, start talking to your customer meaning they are your domain experts. Or this might be the product owner. As soon as you stop discussing data entry and visualisation, you might be getting somewhere.

If you use techniques like Event Storming when holding these discussion, you might discover some behaviour around your domain, and it might be actually quite complex. Some might say this is unnecessary complexity, but make no mistake - accidental complexity is completely different from the actual domain complexity. Of course, some edge cases might not require automation and can be happily resolved by simple human intervention, but some might be very frequent.

One thing to think about is the audit log, typically people want to see how time entries flow through the system. No body wants to see their timesheet amended by someone else without knowing why, when and why.

The approval process could be quite complex as well.

What I mean is that your solution seems to be purely technical. This is not DDD. DDD is about Ubiquitous Language and Bonded Context, not about DTOs, services and repositories.

| improve this answer | |
  • At first I thought CQRS would be completely over blown for this sort of application, until I realized it was a time tracking app. Audit logs. Nuances to how different groups log their time. Oh, and don't forget those old timers with union contracts stipulateing that every third Tuesday is double time after 5 hours of over time the previous week. We had a similar system and every contractor laughed at us when we investigated replacing the system. – Greg Burghardt Mar 7 '17 at 3:26

CQRS can make sense anywhere. CQRS means you separate reads and writes in the application layer, to make them separate concerns, and that's it. Both commands and queries may use the same database, for CQRS alone you do not need to read from a different database than to which you are writing. You can do it, but it's not necessity.

It's event sourcing, which goes so well along with CQRS, that complicates stuff, because your aggregates are no longer objects but a series of events using which they are constructed. Once you start integrating event sourcing to your system then you might start thinking about using a different (maybe a document based) data store for reads to prevent the necessary need to re-hydrate aggregates on each request - but even then that might not be necessary at all. If you have event sourced aggregates which may reach only up to lets say 10 events, managing a separate data store is probably pointless, as hydrating 10 events within the memory itself is very fast anyway.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.