Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Clean Architecture with Spring (Spring I/O 2019)

Clean Architecture with Spring (Spring I/O 2019)

Buzzwords like “Clean Architecture” and “Hexagonal Architecture” have been around for quite some time now. But have you actually seen an application built with one of these paradigms? How do we actually implement such an architecture in a way that the software we create stays flexible and maintainable?

This talk presents the concepts and reasoning behind the buzzwords “Clean Architecture” and “Hexagonal Architecture” and translates them into actual code. Going through an example web application based on Java and Spring, we’ll discuss the full stack ranging from the web layer to the persistence layer. How should we structure our application? Where does the input validation code belong? How do I access my domain logic? How can I let my bounded contexts communicate cleanly? And how does Spring help with all of this? These questions and more will be answered.

Bc7aa56e8e004e4984e954e5e4cb2bc0?s=128

Tom Hombergs

May 17, 2019
Tweet

Transcript

  1. Tom Hombergs @TomHombergs Clean Architecture with Spring

  2. None
  3. Layers

  4. Why bother with Architecture?

  5. Architecture Goals

  6. Architecture Goals

  7. The Ultimate Goal of Architecture The goal of software architecture

    is to minimize the lifetime cost of the software
  8. So ... What‘s Wrong With Layers?

  9. Disclaimer Layers are a solid architecture pattern! But without additional

    restrictions they are prone to design flaws
  10. Database-Driven Design

  11. Blurred Boundaries

  12. Hard-to-test Shortcuts

  13. Hidden Functionality

  14. Do Circles Instead!

  15. SOLID Principles S O L I D Single Responsibility Principle

    Open-Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle
  16. Dependency Inversion Principle SOLID Principles S O L I D

    Single Responsibility Principle Open-Closed Principle Liskov Substitution Principle Interface Segregation Principle
  17. Dependency Inversion Principle

  18. Dependency Inversion Principle We can choose the direction of any

    code dependency* * As long as we have control over the code
  19. Clean Architecture (Robert C. Martin)

  20. Single Responsibility Principle Dependency Inversion Principle SOLID Principles S O

    L I D Open-Closed Principle Liskov Substitution Principle Interface Segregation Principle
  21. Single Responsibility Principle

  22. Single Responsibility Principle A module* should have only one reason

    to change * Read: class, package, component, architecture element, software entity, …
  23. Single Responsibility Principle – Macro Level

  24. Single Responsibility Principle – Macro Level

  25. Domain-Driven Design Only a Domain-Centric Architecture allows Domain-Driven Design

  26. Single Responsibility Principle – Micro Level

  27. Single Responsibility Principle – Micro Level

  28. Do Hexagons Instead!

  29. Hexagonal Architecture / Ports & Adapters (Alistair Cockburn)

  30. Choose your Polygonal Style

  31. Use Cases with a Single Responsibility in a Hexagonal Architecture

  32. Quiz: What does this Application do?

  33. Quiz: What does this Application do?

  34. Let‘s Get Our Hands Dirty! Code Example: https://github.com/thombergs/clean-architecture-example

  35. Implementing a Use Case Code Example: https://github.com/thombergs/clean-architecture-example

  36. Implementing a Persistence Adapter with Spring Boot Code Example: https://github.com/thombergs/clean-architecture-example

  37. Implementing a Web Adapter with Spring Boot Code Example: https://github.com/thombergs/clean-architecture-example

  38. Spring & Clean Architecture Spring doesn't care about which architecture

    we're implementing Spring is easily held at arm's length Spring helps to test isolated parts of our architecture
  39. Mapping Strategies

  40. Mapping Strategies – Two Way Mapping

  41. Mapping Strategies – No Mapping

  42. Mapping Strategies – Full Mapping (Command Pattern per Use Case)

  43. Mapping Strategies – Mix & Match!

  44. Enforcing the Architecture

  45. Enforcing the Architecture - Separate Build Artifacts

  46. Enforcing the Architecture - ArchUnit @Test void validateRegistrationContextArchitecture() { HexagonalArchitecture

    .boundedContext("io.reflectoring.copyeditor.registration") .withDomain("domain") .withAdapters("adapter") .incoming("in.web") .outgoing("out.persistence") .and() .withApplicationLayer("application") .services("book") .services("invitation") .incomingPorts("port.in") .outgoingPorts("port.out") .and() .withConfiguration("configuration") .check(allClasses()); }
  47. Enforcing the Architecture - Moduliths https://github.com/odrotbohm/moduliths

  48. Enforcing the Architecture - Java Module System Yes, it will

    probably work … … but I'm used to having 5 years of time to learn each new Java version.
  49. Conclusion

  50. Benefits of a Domain-Centric Architecture

  51. Drawbacks of a Domain-Centric Architecture

  52. Tom Hombergs @TomHombergs Thanks for your Patience! https://geni.us/dirty-hands-springio Grab the

    e-book for free …