transformation happens when you shift paradigm
In this post, you can find more about: Forming Squad Structure following Domain Driven Design. I would recommend to read the following articles but you can skip if you are already familiar:
- Building a Team Charter for Agile Teams
- Lessons that I have learned around why organizations fail at transformation
- How to build an engineering culture that boosts product experience
- A simple approach on Product Management
- How to structure teams and forms of collaboration
- The rise of Platform Engineering Squads
- Fundamental technical pieces of achieving business agility, scaling up capabilities as well as microservices and microfrontend architecture.
What is Domain Driven Design?
Microservices have a symbiotic relationship with domain-driven design (DDD) — a design approach where the business domain is carefully modeled in software and evolved over time, independently of the plumbing that makes the system work. I see this pattern coming up more and more in the field in conjunction with streaming as well as search capabilities. Everybody is talking about creating an agile and flexible architecture with microservices, a term that is used today in many different contexts. Although microservices are not a free lunch, they do provide many benefits, including decoupling. Decoupling is the process of organizing a system around business capabilities to form an architecture that is decentralized.
DDD is a [software] design discipline where you
- Grasp the domain
- Agree on a language
- Express it in shared models
- Embrace complexity
- Separate models in contexts
- … and evolve them continuously
Bounded Context is a central pattern in Domain-Driven Design. It is the focus of DDD’s strategic design section which is all about dealing with large models and teams. DDD deals with large models by dividing them into different Bounded Contexts and being explicit about their interrelationships.
The Bounded Context Canvas is a collaborative tool for designing and documenting the design of a single bounded context. You can read more about the canvas and how to classify the key architectural decisions and document it in here, also the uber example of DDD.
If you are interested to see a sample code on applying DDD on Banking, please refer to GitHub Repo which is based on maven, spring boot and swagger (open-api). Choosing aggregate boundaries is fundamentally a simple equation where we trade-off the following criteria:
- Correctness: enforcing business rules which should never be violated
- Concurrency: ensuring users can work in parallel without un-necessarily affecting each other
- Complexity: large complex aggregates or asynchronous processes (often necessary for Eventual Business Rules) can increase maintenance costs and reliability of software applications
- Performance: optimizing the responsiveness of the system by not having to load and save large data payloads from the database
Finding the right balance is where the challenge lies, and it is a skill.
Time and resources are limited. How we spend our time and apply our resources when developing software systems is possibly the most fundamental and difficult challenge. Of all the things we could be doing, what should we do and how much quality and rigour should we invest?
A natural tendency for software engineers is to gravitate towards the most technically interesting challenges. I can confirm from my own personal experiences, although it’s not always the case.
Developers who follow a Domain-Driven Design approach, however, have a counter-balance. A concept known as the Core Domain. The Core Domain(s) are parts of the system with the highest return on investment for the business.
As developers, we should seek out the Core Domains to help us focus on delivering the biggest impact and not being drawn to technically-interesting but low-ROI features.
Core Domains are accompanied by Supporting Domains and Generic Domains. Supporting Domains are business necessities, they contain business concepts related to the domain, but there is limited ROI. Generic Domains represent concepts not-unique to our domain, such as user identity, sending emails, taking payments — we should consider buying SaaS or using open source instead of building Generic Domains. Nick has beautifully illustrated the domain types:
According to this definition, a Core Domain is an area of the domain with the opportunity for high business differentiation. This represents a compelling ROI. In addition, the implementation must have at-least a reasonable level of complexity (model complexity). If a simple forms over data (aka CRUD) solution will suffice, we shouldn’t waste time over-engineering.
The banking application in itself will have sub-domains and they can be core, supporting, or generic domains. Indeed, domain driven analysis is done at multiple levels. This is the problem space in which we identify the sub-domains that exist or are needed, we relate the sub-domains that are necessary to solve the problem, and deliver the new core domain. Distill the domain knowledge and mark them as core, supporting, or generic sub-domains.
Business-Led Pace Layering
I am inspired by MuleSoft API-Led connectivity pattern which also helps me to use to make a proposal later in this post on how to structure a tribe following DDD and Pace Layering.
What is Connectivity Pattern?
In simplistic terms, API led connectivity pattern is a way to classify and build the different types of APIs used in an enterprise — while specifying the high level functionality they are expected to implement. There are three main categories (or layers) of APIs in the API led connectivity pattern:
- System APIs — these usually access the core systems of record and provide a means of insulating the user from the complexity or any changes to the underlying systems. Once built, many users, can access data without any need to learn the underlying systems and can reuse these APIs in multiple projects.
- Process APIs — These APIs interact with and shape data within a single system or across systems (breaking down data silos) and are created here without a dependence on the source systems from which that data originates, as well as the target channels through which that data is delivered.
- Experience APIs — Experience APIs are the means by which data can be reconfigured so that it is most easily consumed by its intended audience, all from a common data source, rather than setting up separate point-to-point integrations for each channel. An Experience API is usually created with API-first design principles where the API is designed for the specific user experience in mind.
Advantage of the API Led connectivity pattern are multi fold like:
- Determine complexity and help in effort estimation
- Increased re-usability of APIs (only one API per the intended usage)
- Clearly outline the key life cycle elements of the API like Owner, frequency of change
- Identify operational and monitoring requirements
When the entire organization adopts what is known as API-led connectivity, everyone in the business is empowered to access their best capabilities in delivering applications and projects through discovery, self-service, and reuse. API-led connectivity not only depends on three categories of reusable APIs to compose new services and capabilities, but also decentralizes and democratizes access to enterprise data. Central IT produces reusable assets, and in the process unlocks key systems, including legacy applications, data sources, and SaaS apps. Central IT and other teams can then reuse these API assets and compose process level information. Then, app developers can discover and self-serve on all of these reusable assets, creating the experience layer of APIs and ultimately the end-applications. This API-led approach to integration increases agility, speed, and productivity.
A bit of Change
Before we get into using DDD and these layering, I am going to change the layers a bit into following model, I will give more example later
- Experience Journeys, these are customer-facing journeys that are independent but able to embed to other journeys in order to help to increase drop-offs, conversion rates, up-sell, cross-sell or any other reasons to deliver the total experience
- Process Microservices
- System Microservices
and finally now,
Structuring Tribe using DDD and Business-Led Layering
The Spotify model is a people-driven, autonomous approach for scaling agile that emphasizes the importance of culture and network, also helps you to scale up your engineering teams. It has helped Spotify and other organizations increase innovation and productivity by focusing on purpose, autonomy, mastery, communication, accountability, and quality. The Spotify model isn’t a framework, as Spotify coach Henrik Kniberg noted, since it represents Spotify’s view on scaling from both a technical and cultural perspective. It’s one example of organizing multiple teams in a product development organization and stresses the need for culture and networks.
… the Spotify model focuses on how we structure an organization to enable agility.
now for our example in banking, how do we design squads following DDD and Layers: