Domain-Driven Design with Java - A Practitioner’s Guide

Book description

Adopt a practical and modern approach to architecting and implementing DDD-inspired solutions to transform abstract business ideas into working software across the entire spectrum of the software development life cycle

Key Features

  • Implement DDD principles to build simple, effective, and well-factored solutions
  • Use lightweight modeling techniques to arrive at a common collective understanding of the problem domain
  • Decompose monolithic applications into loosely coupled, distributed components using modern design patterns

Book Description

Domain-Driven Design (DDD) makes available a set of techniques and patterns that enable domain experts, architects, and developers to work together to decompose complex business problems into a set of well-factored, collaborating, and loosely coupled subsystems.

This practical guide will help you as a developer and architect to put your knowledge to work in order to create elegant software designs that are enjoyable to work with and easy to reason about. You'll begin with an introduction to the concepts of domain-driven design and discover various ways to apply them in real-world scenarios. You'll also appreciate how DDD is extremely relevant when creating cloud native solutions that employ modern techniques such as event-driven microservices and fine-grained architectures. As you advance through the chapters, you'll get acquainted with core DDD’s strategic design concepts such as the ubiquitous language, context maps, bounded contexts, and tactical design elements like aggregates and domain models and events. You'll understand how to apply modern, lightweight modeling techniques such as business value canvas, Wardley mapping, domain storytelling, and event storming, while also learning how to test-drive the system to create solutions that exhibit high degrees of internal quality.

By the end of this software design book, you'll be able to architect, design, and implement robust, resilient, and performant distributed software solutions.

What you will learn

  • Discover how to develop a shared understanding of the problem domain
  • Establish a clear demarcation between core and peripheral systems
  • Identify how to evolve and decompose complex systems into well-factored components
  • Apply elaboration techniques like domain storytelling and event storming
  • Implement EDA, CQRS, event sourcing, and much more
  • Design an ecosystem of cohesive, loosely coupled, and distributed microservices
  • Test-drive the implementation of an event-driven system in Java
  • Grasp how non-functional requirements influence bounded context decompositions

Who this book is for

This book is for intermediate Java programmers looking to upgrade their software engineering skills and adopt a collaborative and structured approach to designing complex software systems. Specifically, the book will assist senior developers and hands-on architects to gain a deeper understanding of domain-driven design and implement it in their organization. Familiarity with DDD techniques is not a prerequisite; however, working knowledge of Java is expected.

Table of contents

  1. Domain-Driven Design with Java – A Practitioner’s Guide
  2. Forewords
  3. Contributors
  4. About the authors
  5. About the reviewer
  6. Preface
    1. Who this book is for
    2. What this book covers
    3. To get the most out of this book
    4. Download the example code files
    5. Download the color images
    6. Conventions used
    7. Get in touch
    8. Share Your Thoughts
  7. Part 1: Foundations
  8. Chapter 1: The Rationale for Domain-Driven Design
    1. Why do software projects fail?
      1. Inaccurate requirements
      2. Too much architecture
      3. Too little architecture
      4. Excessive incidental complexity
      5. Uncontrolled technical debt
      6. Ignoring non-functional requirements
    2. Modern systems and dealing with complexity
      1. How software gets built
      2. Complexity is inevitable
      3. Optimizing the feedback loop
    3. What is DDD?
      1. Understanding the problem using strategic design
      2. Promoting a shared understanding using a ubiquitous language
      3. Implementing the solution using tactical design
    4. Why is DDD relevant? Why now?
      1. Rise of open source
      2. Advances in technology
      3. Rise of distributed computing
    5. Summary
    6. Further reading
  9. Chapter 2: Where and How Does DDD Fit?
    1. Architecture styles
      1. Layered architecture
      2. Vertical slice architecture
      3. Service-oriented architecture (SOA)
      4. Microservices architecture
      5. Event-driven architecture (EDA)
      6. Command Query Responsibility Segregation (CQRS)
      7. Serverless architecture
      8. The big ball of mud
      9. Which architecture style should you use?
    2. Programming paradigms
      1. Object-oriented programming
      2. Functional programming
      3. Which paradigm should you choose?
    3. Summary
  10. Part 2: Real-World DDD
  11. Chapter 3: Understanding the Domain
    1. The domain of international trade
    2. International trade at KP Bank
    3. Understanding international trade strategy at KP Bank
      1. The business model canvas
      2. The lean canvas
      3. Impact maps
      4. Wardley maps
    4. International trade products and services
    5. Summary
    6. Further reading
  12. Chapter 4: Domain Analysis and Modeling
    1. Technical requirements
    2. Understanding a letter of credit
    3. An LC issuance application
    4. Enhancing shared understanding
    5. Domain storytelling
      1. Using DST for an LC application
    6. EventStorming
      1. Introducing EventStorming
      2. Using EventStorming for the LC issuance application
    7. Summary
    8. Further reading
  13. Chapter 5: Implementing Domain Logic
    1. Technical requirements
    2. Continuing our design journey
    3. Implementing the command side
      1. Tooling choices
    4. Bootstrapping the application
      1. Identifying commands
      2. Identifying aggregates
      3. Test-driving the system
      4. Implementing the command
      5. Implementing the event
      6. Designing the aggregate
    5. Persisting aggregates
      1. State-stored aggregates
      2. Event-sourced aggregates
    6. Persistence technology choices
      1. Which persistence mechanism should we choose?
      2. Enforcing policies
    7. Summary
    8. Further reading
  14. Chapter 6: Implementing the User Interface – Task-Based
    1. Technical requirements
    2. API styles
      1. CRUD-based APIs
      2. Task-based APIs
      3. Task-based or CRUD-based?
    3. Bootstrapping the UI
    4. Implementing the UI
      1. MVVM primer
      2. Creating a new LC
      3. Declarative view
      4. View delegate
      5. View-model
    5. Summary
    6. Further reading
  15. Chapter 7: Implementing Queries
    1. Technical requirements
    2. Continuing our design journey
    3. Implementing the query side
      1. Tooling choices
      2. Identifying queries
      3. Creating the query model
      4. Query-side persistence choices
      5. Exposing a query API
      6. Advanced query scenarios
    4. Historic event replays
      1. Types of replays
      2. Event replay considerations
      3. Event design
      4. Event handlers with side effects
    5. Summary
    6. Further reading
  16. Chapter 8: Implementing Long-Running Workflows
    1. Technical requirements
    2. Continuing our design journey
    3. Implementing sagas
      1. Orchestration
      2. Choreography
    4. Handling deadlines
    5. Summary
    6. Further reading
  17. Chapter 9: Integrating with External Systems
    1. Continuing our design journey
    2. Bounded context relationships
      1. Symmetric relationship patterns
      2. Asymmetric relationship patterns
    3. Implementation patterns
      1. Data-based
      2. Code-based
      3. IPC-based
    4. Summary
    5. Further reading
  18. Part 3: Evolution Patterns
  19. Chapter 10: Beginning the Decomposition Journey
    1. Continuing our design journey
    2. Decomposing our monolith
    3. Changes to frontend interactions
      1. Protocol options
      2. Transport format
      3. Compatibility and versioning
      4. REST APIs
      5. Changes for event interactions
    4. Changes in database interactions
      1. Data migration
      2. Cut-over
    5. Summary
    6. References
  20. Chapter 11: Decomposing into Finer-Grained Components
    1. Continuing our design journey
      1. Saga as a standalone component
      2. Commands and queries as standalone components
      3. Distributing individual query components
    2. Even more fine-grained decomposition
      1. Effects on the domain model
    3. Decomposing the frontend
    4. Where to draw the line
    5. Team organization
    6. Summary
    7. Further reading
  21. Chapter 12: Beyond Functional Requirements
    1. Observability
      1. Technology metrics
      2. Business metrics
      3. DevOps metrics
    2. Consistency
    3. Performance and scale
    4. Trunk-based development
    5. Continuous testing
      1. Contract testing
      2. Mutation testing
      3. Chaos testing
    6. Deployment automation
    7. Refactoring
      1. Breaking an existing monolith
      2. Merging into coarse-grained bounded contexts
    8. Invocation style
      1. Synchronous invocation
      2. Asynchronous invocation
    9. Logging
      1. Segregating logging code
      2. Dealing with sensitive data
      3. Log format
      4. Log aggregation
      5. Tracing
    10. Versioning
      1. Components
      2. APIs
      3. Data
    11. Summary
    12. Closing thoughts
    13. Why subscribe?
  22. Other Books You May Enjoy
    1. Packt is searching for authors like you
    2. Share Your Thoughts

Product information

  • Title: Domain-Driven Design with Java - A Practitioner’s Guide
  • Author(s): Premanand Chandrasekaran, Karthik Krishnan
  • Release date: August 2022
  • Publisher(s): Packt Publishing
  • ISBN: 9781800560734