Implementing Domain Driven Design with Spring by Maciej Walkowiak @ Spring I/O 2024

Поділитися
Вставка
  • Опубліковано 25 лис 2024

КОМЕНТАРІ • 73

  • @nikolairomanov6054
    @nikolairomanov6054 4 місяці тому +26

    I find it kidna funny that we say that "classical layered approach" can work for small projects and then we try to show benefits of DDD on the same small examples.
    But sometimes (quite often) in big systems we choose verbosity to provide better clarity and reduce coupling.
    To me it was terrifying what happened to our domain by the end of the presentation.

  • @kevindurant4952
    @kevindurant4952 5 місяців тому +34

    00:00 - 04:22 Introduction
    04:23 - 04:58 What is DDD?
    04:58 - 06:08 What does DDD mean for developers: Understanding the domain.
    06:08 - 06:32 What does DDD mean for developers: Split big domains into subdomains.
    06:32 - 08:00 What does DDD mean for developers: Develop an ubiquitus languages.
    08:00 - 08:35 What does DDD mean for developers: Develop a domain model + separate domain model from implementation details.
    08:35 - 09:24 The Old Testament and the New Testament.
    09:28 - 13:20 What is the domain model: introduction.
    13:40 - 16:23 Existing Library Software: anemic domain anti-pattern.
    16:24 - 17:14 Why we don't want this approach.
    17:24 - 20:02 DDD Library: User Stories and what they tell us.
    20:02 - 20:42 DDD Library: Implementation start.
    20:42 - 25:20 DDD Library: Creating the domain model.
    25:20 - 26:40 DDD Library: JPA vs separate domain models.
    26:40 - 30:15 DDD Library: adapting domain model to work with JPA (@Embedded and @EmbeddedId).
    30:15 - 33:27 DDD Library: Creating the Copy class and a note on @ManyToOne in DDD (31:24).
    33:27 - 37:00 DDD Library: implementing the use-cases, the wrong way.
    37:00 - 39:53 DDD Library: implementing the use-cases, the correct way using dependency inversion.
    39:53 - 41:30 DDD Library: Service Taxonomy using custom Java @Annotations.
    41:30 - 45:07 DDD Library: Bounded Context #2 Lending books.
    45:08 - 46:03 Enforcing module separation using Modulith tests.
    46:04 - 48:50 What if some modules need to depend on eachother? Solution: extend AbstractAggregateRoot and work event driven.
    48:51 - 50:17 Outro.

    • @rapoliit
      @rapoliit Місяць тому

      I say Really thank you.

  • @ykhi
    @ykhi 5 місяців тому +10

    I think what we usually did was to create a BookEntity class in the infra layer and together with Mapper classes(that maps domain object to corresponding database entity object), this way we separate the domain object definitions from the database variations of it according to the onion architecture's separation of concerns

  • @roman-proshin
    @roman-proshin 5 місяців тому +7

    The code will look much better once we replace JPA with Spring Data: it supports immutable entity classes out of the box, it kinda forces identifying aggregates.

  • @Alx-gj2uz
    @Alx-gj2uz 3 місяці тому +1

    I found the idea of coding the implementation as userstories / usecases extremely insightfull, seeems to work really well with ddd. Goes hand in hand with good architecture documentation and requirements engineering and is pretty good from a perspective as "code as documentation". Never thought of this.
    Its roughly at timecode 34:30

  • @atrucktive
    @atrucktive 3 місяці тому +5

    25:27 DDD code review.
    - You don’t need to RE-validate the ISBN value object.
    - Domain coupled to infrastructure (framework)

    • @williamsbotchway2471
      @williamsbotchway2471 Місяць тому +1

      - Domain coupled to infrastructure (framework). This is bullshit. Java got to fix this and have a better way to deal with this.

  • @YZ-ix3dn
    @YZ-ix3dn 5 місяців тому +17

    I feel this approach a bit confusing especially when you pass repository into the domain entity. What can be more straightforward than having 3 main layers (Controller, Services, Repositories). In real life scenarios, there might be a lot of communication with different systems, so putting all that logic in service layer looks more reasonable for me. And basically these UseCase classes could be in fact small granular services e.g. AddBookToCatalogService.

    • @atrucktive
      @atrucktive 3 місяці тому

      That’s just upgrading the old MVC to MCV 2.0 (with Trushtero services)
      With this approach you are going to really take care of the business domain and clean architecture

  • @TechTalksWeekly
    @TechTalksWeekly 5 місяців тому +4

    This talks is excellent and it has been featured in the last issue of Tech Talks Weekly newsletter 🎉
    Congrats Maciej!

  • @devolajide
    @devolajide 5 місяців тому +3

    Finally, I have been waiting for the video to be uploaded.

  • @ogyct
    @ogyct 4 місяці тому +1

    Can't say I liked it. In the very beginning we say, that our domain should be framework agnostic and yet we introduce jpa entities right into it.
    Next we implement BookSearchService in infrastructure. Oh wait, let's just put it in application package just because that's the rule. What is the difference between infrastructure and application then?
    When creating Loan domain, we introduce LoanRepository argument into its constructor. Why?
    And there's much more I don't get about it. In the end, even if somehow manage to understand it, how am I supposed to explain it to the others.

  • @MateuszNaKodach
    @MateuszNaKodach 3 місяці тому +1

    The repository call in the domain object even does not guarantee the rule is not broken, because it's not transactional consistent...
    I think no-one should do something like that. There is a lack of some Availability concept in the domain.

  • @aditya789101
    @aditya789101 4 місяці тому

    Clear and detailed. Thank you for the efforts!

  • @avalagum7957
    @avalagum7957 5 місяців тому +6

    record BookId(UUID)
    record ISBN(String)
    ....
    These wrappers create more tasks for the GC. I'm waiting for the day when the Java compiler supports new type/opaque type like the Scala compiler (i.e. we still have BookId and ISBN but the compiler will remove them while still keeping all the validations inside them).

    • @nikolairomanov6054
      @nikolairomanov6054 4 місяці тому +3

      If you start to carry about java GC optimisations like this, you probably need to get rid of all "spring-data" and lots of other stuff first.

  • @MudasarRauf
    @MudasarRauf 5 місяців тому +2

    very nice and informative talk

  • @ederortega9606
    @ederortega9606 8 днів тому

    what is the difference betwen service and use case

  • @pentasung
    @pentasung 4 місяці тому +1

    Why is Book an entity and not a VO in the catalog domain ?

  • @ralte89
    @ralte89 Місяць тому

    Thanks for this talk, very informative.
    For creating an audit trail of a user, would events, or Aspect be prefered ? It seems that with spring modulith we can achieve the same result of using Aspect. If we use events we can even have a module audit, and have the audit persistence and reading of such decoupled

  • @marceloguzman2848
    @marceloguzman2848 5 місяців тому +1

    nice presentation, mr. homelander

  • @AlexanderBondarenko-w9f
    @AlexanderBondarenko-w9f 4 місяці тому

    Thanks for the presentation! Is a repository of non-DDD example of library available somewhere?

  • @julianruppel9171
    @julianruppel9171 4 місяці тому

    Perfect talk, enjoyed it a lot

  • @Beny_gx
    @Beny_gx 2 місяці тому

    If one uses jpa entity classes that need mapping to domain objects there will be quite so code gymnastics to lazy load collections because mapping them will always result in an eager fetch

  • @FiruzzZ-777
    @FiruzzZ-777 2 місяці тому

    so all the control/validation/restrictions/events will be in an Entity/POJO, services and business layers are empty :/ ... you manage the entire flow of a project by the actions performed against "the domain"

  • @isbey9595
    @isbey9595 2 місяці тому

    There is something codesmell I think. Domain layer should be written as pure as possible. Repository definition and entity definitions violate something here.Tests of the domain layer should also be written independently. But there is JPA dependency here.

  • @ZapOKill
    @ZapOKill 3 місяці тому

    I thought that the combination of @Entity and @Data is discouraged.

  • @dimitricharles9784
    @dimitricharles9784 5 місяців тому +2

    Nice talk. Just one question, in the BookSearchService takes an Isbn as parameter, but the Isbn type is defined in domain layer but used in the app and infrastructure layer. Would passing a String representation of a isbn sufficient ?

    • @roman-proshin
      @roman-proshin 5 місяців тому +2

      It’s absolutely fine as any of these “layers”/“modules” can use domain classes. That’s the whole purpose of the design: keep the domain module pure and clean, and have all the rest of the application to use that domain to actually get a working application.

    • @dimitricharles9784
      @dimitricharles9784 5 місяців тому

      ​@@roman-proshin Oh ok I have never thought of it that way. So there is no mapping to a DTO needed when returning an entity from the domain to a Restful request ?

    • @diego.schmidt
      @diego.schmidt 5 місяців тому

      @@dimitricharles9784 No. Use DTOs only when necessary

  • @scerrisebastien
    @scerrisebastien 3 місяці тому

    Interesting but Domain driven design I still don't get the benefits on micro services at least. A lot of classes and complexity. Yes small classes are simpler to maintain.
    Anyway I will continue the journey with the videos you mentioned.

  • @haroldpepete
    @haroldpepete 21 день тому

    ummm i've read in a lot of places about how bad is uuid like a id in database, it aint sortable and the index may be messy

  • @hackstreet781
    @hackstreet781 Місяць тому

    After watching this video, it feels like my 7 years of experience was a lie. It is so tough to implement by ourselves.

  • @cariyaputta
    @cariyaputta 4 місяці тому

    Nice talk. Thanks.

  • @mrowox
    @mrowox 4 місяці тому

    Can DDD be employed to develop any type of software of is this peculiar to certain type of softwares?

    • @AntonioDoesMetal
      @AntonioDoesMetal 4 місяці тому +3

      Just my 2 cents DDD is a design pattern specifically for somewhat complex to complex business domains. If you're doing scripting or building small apps that don't have tons of complex business logic and entities than best to stick with what you know. However if you're working with a complex business domains DDD really shines and shows you how badly you've been building software lol. Like imagine a freight shipping company that deals with delivers packages internationally. There are tons of different laws you may have to deal with from different countries in a single trip. Between that and varying currencies, delays, timezones etc you could imagine there's tons and tons of "tribal knowledge" that the business users know about how it all works that's probably not really documented anywhere. So when building software for those people to solve a problem they have, it's important that you model your software correctly so it doesn't implode as things change and code needs to be modified/extended. Writing the code is almost secondary, design and understanding your users domain space is primary. Hope this helps

    • @AJewFR0
      @AJewFR0 2 місяці тому +1

      Implementing DDD chapter 1 has some guidance on answering this question. If you start talking to a domain expert to try to understand the problem and you keep finding caveats (i get concerned after 3-5 branches down a certain process pipeline), it is time to go back and apply DDD more formally. But you should consult the book for a more holistic answer because every domain is different. But if it is complex to you and your customer, it is probably complex.

  • @aurevoir641
    @aurevoir641 2 місяці тому +6

    normal people at 5 am: sleeps
    devs at 5 am: watches this video

    • @nmprecious
      @nmprecious 23 дні тому

      I just woke up at 5:00am to watch this. It's 5:08am now.

  • @avwie132
    @avwie132 Місяць тому +1

    Mixing domain and framework. Nice

  • @voult89
    @voult89 5 місяців тому +5

    In my opinion, the domain shouldn't know anything about how the entity will be saved, updated or whatever, and where it would happen.
    For the domain it should be an abstraction.
    For example, you can decide not to use JPA, and use JDBC instead. And if you're designed your application correctly, you won't change anything in domain module, you won't even recompile it, and only persistence module will be changed.
    And modulith only help you design you monolith application, not microservice with DDD. But gradle can, since for each module (presentation, persistence, use cases, domain) you can set it's own dependencies. And, for example, domain will never depend on use cases, and you can even write tests for that. And you don't even need to recompile inner modules, when you change anything in outer modules.

    • @rolandjost3823
      @rolandjost3823 5 місяців тому +1

      Indeed, your vision or your approach is correct. In addition, I noticed that there are two architectural approaches to doing DDD. Obviously the one you described above, and the one he presents in his talk based on Spring Data JDBC (AggregateRoot) using JPA annotations.
      Your approach is ideal since it avoids a decoupling between the business domain and the infrastructure layer, however it requires a lot of DTO.
      In short, note that the DDD approach is a free approach, since it is based on a set of good practices (TDD, BDD, CLEAN ARCHI and others). But does not define any specific architecture.
      Personally I recommend using the one that will allow you to deliver your software faster

    • @FernandoDBozzo
      @FernandoDBozzo 5 місяців тому

      @@rolandjost3823
      Fast Delivery in this way normally implies slowing maintenance in the future. I don't know if everything is valid just for Fast Delivery...

    • @MrVitalirapalis
      @MrVitalirapalis 5 місяців тому

      I agree with you @voult89, how would you structure your microservice ddd project? Can you provide some example. Just module, package names and so on.

    • @Boss-gr4jw
      @Boss-gr4jw 4 місяці тому +1

      If you have an interface which exposes save function and it is implemented in infrastructure layer, then the domain will never know how something is persisted or which is the underlying technology, this is exactly what was demonstrated here.

    • @voult89
      @voult89 4 місяці тому

      @@Boss-gr4jw Nope. He used annotation "Entity" and to use it as a JPA entity he made domain "Entity" mutable, created no arg constructor for JPA and so on. So, your domain module already knows what technology will be used.
      data-JDBC, for example, doesn't need any of this staff.

  • @abccbaandy
    @abccbaandy 5 місяців тому +1

    Great talk, but still don't see any chance to use this in real world biz logic.
    For example:
    It do valid in domain object, but what if I got a new requirement that I need bypass or add some valid in some biz logic? It seems hard to do this new task.
    Instead, with old school POJO way, it's easy.

  • @williamsbotchway2471
    @williamsbotchway2471 Місяць тому +2

    The problem with keeping the data model with the domain model is a problem with java and spring. C# with dotnet solves the problem in an much elegant way. This makes C# a go to framework when thing about DDD. U should alway keep your domain model free from any infastructure concerns. Unfortunately spring jpa makes such aproach look like a boilerplate. Is this not a violation of the single responsibility principles?

  • @morkhoudia9
    @morkhoudia9 5 місяців тому

    Great talk

  • @nil7444
    @nil7444 5 місяців тому +1

    the repository call in the domain object is weird, just build a specification class and pass that instead.

    • @anton-tkachenko
      @anton-tkachenko 5 місяців тому

      Yeah, that's weird, especially when you need to create / update 10 000 entities...

  • @kevinmaltby4202
    @kevinmaltby4202 22 дні тому

    Another year, another 'shiny concept'. Seems like this one is going to take us back to monoliths with the addition of confusion of what 'domain driven design' is. Seems like its someone else's turn in the spotlight to sell books and courses. I note hardly anyone talks about having a multi-module spring project e.g. multi-module Maven to decompose an application into. A lot less confusing than trying to introduce yet another concept/buzz-phrase/buzz-idea.

  • @king20031
    @king20031 Місяць тому

    axon is the best ddd framework in java word

  • @AbdelrhmanHussien-sx8vb
    @AbdelrhmanHussien-sx8vb 2 місяці тому

    I feel like if I found a treasure

  • @SomeRandomGuyOnYT507
    @SomeRandomGuyOnYT507 5 місяців тому +8

    This might looks fancy but In my work experience, this way of modeling microservice is worst thing you can do in fast developing world. I want my developers to get features out as fast as possible with proper testing. I don't want them to waste time in managing packages.
    controller, service, entities, repositories, util, helper. with No shitty one interface, one class thing.
    just keep it simple !! You are not gonna need it.

    • @anton-tkachenko
      @anton-tkachenko 5 місяців тому

      One interface is good. You have a list of use cases in one place. I think they used to call it a facade :)
      If needed, implementation can be split into classes

    • @SomeRandomGuyOnYT507
      @SomeRandomGuyOnYT507 4 місяці тому

      @@anton-tkachenko when needed your IDE can refactor out an interface in just 2 clicks. 🫠

    • @Boss-gr4jw
      @Boss-gr4jw 4 місяці тому +2

      That's how you end up with the anemic model and god classes which are impossible or hard to test. Also you end up putting functions together into services which are not related at all. This all results in so fragile code, hard to change, every change requires full recompilation of unrelated classes, slow builds, slow tests etc. There is a reason for why you should be designing into interfaces and smaller classes and packages. For very small service there is no reason not to put everything into same package, if it really is small.

    • @phamnguyen3083
      @phamnguyen3083 4 місяці тому +1

      I know many people love this approach because they never write a single test, so one big class works for them.

    • @puraverdad2022
      @puraverdad2022 3 місяці тому +4

      this approach intend isn't for simple projects or APIs (for that u can still use plain MVC), when a project grows and this involves scaling in complexity, let say after 1.5 year aprox, when more business rules are added if you don't have a Clean Architecture then u'll find out that the code is a mess and highly coupled, then making adaptations among business rules look really dirty in legacy approaches. Making code as faster as possible is the opposite of making high quality code (I prefer having code well organized and tested that can adapt in the future easily than writting fast code for a user story than will be broken in the near future)

  • @mohammadtoficmohammad3594
    @mohammadtoficmohammad3594 5 місяців тому +1

    Thank you very useful