9. Problem distillation
â This is not business layer only, applies to technical aspects as well!
â Business may benefit early due to smaller solutions being ready faster than all at
once
â Communicate with business to find critical ones - focus on them first
14. DDD - Bounded Context
â Logical barriers of the model that give solution to a problem
â Same entity across Bounded Contexts may have different names and properties
â Bounded Context may be considered as a logical boundary in monolith application or
Microservice
â Helps in non DDD environment too!
17. Use case: Tournaments with schedule
â Tournaments should support multiple systems (single/double elimination, swiss, âŠ)
â Matches are scheduled
â Created matches allow to play a game
Tournaments
Scheduled Matches
18. Use case: Tournaments with schedule
Assumptions:
â Platform already supports matches
Tournaments
Scheduled Matches
Matches
19. Use case: Tournaments with schedule
Business concerns:
â We may require scheduled matches without tournaments in the future
Tournaments Scheduled Matches Matches
20. Use case: Tournaments with schedule
Tournaments Scheduled Matches Matches
Tournaments with
scheduled
(business process)
21. Business process vs lower level components
Business process Lower level components
â Ties components together
â Controls the flow
â Use case naming convention in
code
â Business use case Bounded
Context
â Quite generic/reusable as a
component
â Component specific naming
convention in the code
â Local Bounded Context
22. Use case: Tournaments with schedule
Benefits
â Easier to split work across developers
â Ready to support new feature
â Reusability of components
â Less code in each component
â Very specific business requirementsâ details not spoiling reusable components
25. Following all principles not always possible
â Chasing perfection - endless refactoring
â âBetter working than perfectâ
â Almost everyone may give different solution for the same problem
â Write code in such way (decoupling) to limit scope of changes leaking outside of
given code scope while refactoring
â Be aware of what rules are being broken (SOLID)
26. When there is no time
â Assess price of technical debt and the risk involved
â Is component critical?
â Does current state introduces risks?
â Is the code readable enough?
â In case of refactoring, will I need to change code only within this single component?
â How important is it for business?
â How business will benefit by changing this in comparison to cost of change?
â Does component follow projectâs convention enough?
â How business would benefit from current code despite its quality?
â Will I be able to refactor it later?
â Negotiate scope
â Communicate!
27. Mechanical vs deep refactoring
â Mechanical refactoring usually is cheap and introduces low risk
â Examples:
â Renaming Classes / Interfaces
â Code formatting
â Deep refactoring
â Requires changing actual domain (may introduce new edge cases)
â Within single Bounded Context introduces low to medium risk (unit tests)
â Across many Bounded Contexts introduces medium to high risk (integration test)
28. Common closure principle
The classes in a package should be closed together against the same kinds of changes.
A change that affects a package affects all the classes in that package.
Source: âPrinciples of Package Designâ by Matthias Noback
34. Top directory tree
â Framework
â Communication related (HTTP, Websocket, CLI, ACL, rate limiting, âŠ)
â Application
â Connects business logic with framework
â Implement Domain interfaces (like database, API or other 3rd party libraries)
â Transactions handling
â Catches Domain Events (logging, queueing, sending email)
â Domain
â Completely technology agnostic by using Interfaces
â Contains Components and Shared Kernel
35. Component / Business process - example
â Entities
â Entity1
â Entity2
â Repositories
â Entity1RepositoryInterface
â Entity2RepositoryInterface
â Service
â Tests
36. Component / Business process - notes
â If Entity1 references lots of Entity2 (oneToMany)
â Make separate repository for each Entity
â Foreign keys are ok within Component
â Repositories
â Generic methods (at least)
â Performance optimized methods if needed (counting)
â Service
â Calling methods changes state of Entity
â Tests
â Unit tests
37. Component / Business process - notes
â Tracking - each component may track itâs own domain specific history changes
â Consider tracking more than needed - business will ask soon about KPIs
â To solve storage/performance issue implementation may use NoSQL
â Tracking may be explicit (in domain) or implicit (via tracking dispatched events)
â Passing data to service methods
â Simple types makes testing easier
38. Shared kernel - notes
â Components commonly used by other Components (Event Dispatcher, Base Entity
Classes, Traits, Scheduler)
â Changes may affect other Components
39. Components relation to other components
â Assigning Entity reference to Entity from other component
â In most cases ID is enough (avoid foreign keys)
â Referencing different kinds of Entities by storing Context Type and Context ID, example:
â Type Match and Match ID
â Type Tournament and Tournament ID
40. Relation on code level vs service level
â Code level
â Single app instance
â Higher level components may extend lower level components with plugins
â Coupled code vs Dispatching Events
â Service level (SOA / Microservices)
â No code sharing
â Access only via API / Messaging
41. Technical components
â Do not mix low level technical components with Domain
â Naming basing on Context:
â Image processing
â Communication (Websockets / HTTP / Queue)
â Domain Framework (ie Interfaces for Commands, Dispatcher)
â Addition to 3rd party framework (Symfony / Laravel)
44. What if I donât have full CQRS?
â Commands will use Services from domain
â Queries
â In simplest form may use existing Repositories from Components
â Consider separate Repository Interface for Commands/Services and Queries
â Keep adding counters / redundant data step by step avoid complex joins and speed up queries
â Over time Query Repository may use more advanced solutions
50. My Class
â Is it technical, domain or connecting domain with framework?
â Is it for state change or reading?
â Is it generic or application/use case specific?
â Does it have state?
â Which properties are optimization purposes?
â What Bounded Contexts it should be aware of?
51. Summary
â Chosen approach depends on teamâs experience, available time, projectâs lifespan
â Seek for Bounded Context in non DDD components/layers too!
â Coupling within Component is good. Unnecessary coupling between Components is
bad.
â There are no strict rules, each team goes their own path
â Introduce new ideas in your project step by step
â Explore, make mistakes, improve