Pragmatic Domain Driven Architecture -1

What is Domain Driven Architecture?

It's a way of decomposing a bigger business problem into smaller subproblems based on the overall business process and problem one is trying to solve. It involves understanding and encompassing business functionality into separate business domains so that each of these business domains fulfil only a subset of the overall business functionality offered by the overall platform. DDA was coined by Eric Evans, in 2004, in his book Domain-Driven Design: Tackling Complexity in the Heart of Software

Bounded context?

Each of these subdomains that is responsible for a part of a business problem is called a bounded context. Why is it called the bonded context? it's because each domain has

  • Clear set of responsibilities that domain has to perform from functional and data perspective , in a way an extension to single responsibility principle

  • Clear set of interactions and data hand-shake , ( i.e. clearly defined API exposing the “domain model” of the domain)

  • Loose coupling with other domains. There is definite interaction between them WITHOUT knowing the intricacies in how the actual data is derives ( blackbox to each other)

A bounded context of a domain is very specific to the business problem ( or the solution ) it tries to solve an cant be generic that can work for diverse business domains. e.g. a order service for food order vs. a trade service to capture a derivatives trade.

Why it’s important?

Like we apply SOLID principles, loose coupling, encapsulation in software engineering/ development, its essential to extrapolate that when forming a front to back architecture, constituting many services.

  • Use and re-use domain knowledge effectively for a key problem and encapsulating that to a domain (and avoiding the need for other to know about the functionality and the complexity of on domain ( e.g. the accounting service dont have to worry about how a trade is captured but only need to know the economics post booking the trade to manage the sub-ledger and accounting logic)

  • Scale up the delivery approach by decomposing the problem to small domains (and small teams - “pods” ) that

    • Can work in true -agile fashion ( == two pizza team size) with in the problem domain

    • Make it self-sufficient w.r.t. design, development and testing ( Imaging how a car is made up of 20,000+ disparate components coming from around the globe)

What pragmatic points to consider?

  • How to define a domain?

    • Each domain and its bounded context MUST make sense from business perspective. The domain should be able to stand on its own from business perspective

      • Without significant dependencies with other services

      • Should be able to cohesively manage the functionality if offers and be the authority for the functions AND the data it owns/governs

      • Do not create artificial technical boundaries as it will come back and bite you later when trying to formulate cross service interactions

    • The domain operations MUST be ACID and transactionally safe. If its dependent on its safeness of data to another service, consider whether that service should be part of your service or re-think on the domain model.

    • Dont think that every service should be a micro service. The Service/ domain MUST make sense from business perspective

  • API and data of a domain

    • The domain MUST only create/update/delete the data it owns/stores and not other’s data. If it has to update data from different domain that needs to be done through other domain’s APIs ( no exposure to underlying data repositories/ data sources)

    • The API / access it exposes MUST provide clear data models encompassing its underlying logical domain model ( as the underlying physical model will be dependent on the data store used)

    • There MUST not be datastore level ( e.g. DB stored procedures ) having transactional boundaries crossing DB objects spanning multiple domains as this will break the segregation in transactional boundaries between different domains

    • A domain MUST ONLY store a immutable reference of a alien domain entity ( e.g. trade booking domain storing the ID of the counterparty, ID of the instrument the trade is booked and not the names + details of those entities).

    • These IDs can be natural and immutable as any change will result in breaking the referential integrity between the domain. As the referential integrity is “loose” between the domains ( no single database level referential integrity constraints) this is a critical principle to ensure cross-domain consistency is maintained.

    • If the physical data objects ( e.g. RDBMS tables, noSQL DB collections ) of different domains are in the same physical database ( for convenience and scale purposes) DO NOT create DB level referential integrity constraints.

  • Inter-domain/service interactions

    • DONT focus on applying two-phase commit type distributed transaction models to ensure transactionality ACROSS different domain.

    • EACH domain MUST be ACID compliant.

    • Also it must be able to define whether the transaction is final or reversible through a “business” process flow ( like cancel order). i.e. the service may have to perform a transactional reversal / compensating transaction” depending on the state of the overall business process.

    • Irrespective of you adopt an orchestration or choreography style communication the transactionality, recoverability, guaranteed processing MUST be managed by EACH service. More on inter-process/inter-domain communication in a later post…..

    • EACH service talk to each other from APIs ( Black box access)

  • Deliverability of the services

    • Having a clear business segregation helps in

      • Constraining clear business domain/functionality

      • Limiting clear interaction model

    • This helps in forming a manageable delivery team constituting “three Amigos” - ( product SMEs, Developers, Testers) that can

      • Own the functional delivery

      • Manage the roadmap of the services

    • This helps in building and maintaining the domain knowledge ensuring sustainability and continuity

    • In my past and current projects, creating “pods” that own respective domains had helped immensely in delivery quality and maintainability

Size (granularity) of services ?

  • While concept of micro services is great , we have to be pragmatic. Hence I tend to drop the “micro” and JUST use “services” in the context of Domain Driven Architecture. The determination of the size is dependent on the principles discussed in above section.

Practicality and scaling DD design and architecture

I intend to cover some practical aspects in domain modelling , layered architecture models and scaling out a DD architecture in a future post….

Previous
Previous

Building reliable, cloud friendly software

Next
Next

Reliable services/processes