Boundaries, Domains & Ownership
Boundaries are the most important architectural material. Parnas’s information-hiding argument, domain-driven design’s bounded contexts, and modern service-ownership practice all point to the same architectural pressure: hide unstable decisions behind a boundary that has a clear language and owner. Bad boundaries make every change cross-cutting. Good boundaries turn complexity into smaller local problems with explicit integration points.
Domain boundaries are not found by looking at tables or controllers. They are found by listening to language, responsibility, cadence of change, invariants, and business capability. “Customer” may mean a marketing lead, an authenticated user, a legal contracting party, a billing account, or a support contact. If one model tries to satisfy all meanings, the architecture becomes ambiguous. Separate models can be integrated; confused models corrupt each other.
Cohesion and Change
A useful boundary groups things that change together and separates things that change for different reasons. Cohesion is not about placing similar nouns together; it is about shared rules. Order pricing, promotion eligibility, tax calculation, inventory reservation, and payment capture may all appear in checkout, but they do not necessarily belong to one module. The question is which rules must be consistent at the same moment and which can evolve independently.
Change history is a strong boundary signal. If compliance rules change monthly while catalog browsing changes weekly and payment integration changes only when providers evolve, forcing them through one release path creates friction. Conversely, splitting one invariant across three services may create distributed transaction pain for no real autonomy. Boundaries should respect both domain meaning and change cadence.
Data Ownership
Data ownership is often where architectural ideals meet reality. If multiple services write the same table, ownership is fictional. If reporting jobs bypass domain APIs and mutate operational state, invariants are unprotected. If every team reads every table directly, schema changes become organization-wide events.
Owning data does not mean hiding all data. It means owning the rules that make the data valid. Other contexts may receive events, query read models, or use published APIs. They should not quietly depend on private storage structures. A private table is an implementation detail; a contract is an architectural commitment.
Boundary Interfaces
Every boundary needs an interface, and not all interfaces are APIs. An interface may be a synchronous endpoint, event stream, file export, shared library, command queue, admin workflow, data product, or human approval process. The architectural question is what the interface promises and what it hides.
Stable interfaces should expose business capabilities rather than internal data shapes. “Create shipment for paid order” is a stronger capability boundary than “insert row into shipments.” “Customer credit changed” is a stronger event than “customer table updated.” Capability-oriented interfaces are easier to evolve because they preserve intent while allowing implementation changes.
Ownership and Team Topology
A boundary without ownership decays. Someone must be accountable for the language, contracts, quality attributes, and runtime behavior inside the boundary. Shared ownership can work for libraries or platforms, but product domains usually need clear owners. Otherwise every team optimizes locally and the domain model becomes a negotiation artifact.
Team topology should follow cognitive load. A stream-aligned team should own a coherent product or domain slice. A platform team should reduce operational and delivery burden without taking ownership away from product teams. An enabling team should teach and accelerate adoption of practices. Complicated subsystem teams should exist only where deep specialist knowledge is genuinely required.
Practice
Pick a messy domain noun such as customer, account, order, product, or subscription. Write at least four meanings used by different stakeholders. Then propose bounded contexts, name the owner of each context, identify the private data each owns, and define one public contract for integration. If the same field appears in multiple contexts, state whether it is copied, derived, or independently meaningful.
References & Further Reading
- David L. Parnas, “On the Criteria To Be Used in Decomposing Systems into Modules” (Communications of the ACM, standard copyright)
- Domain-Driven Design: Tackling Complexity in the Heart of Software by Eric Evans (Addison-Wesley, standard copyright)
- Building Microservices by Sam Newman (O’Reilly, standard copyright)
- Microservices Patterns by Chris Richardson (Manning, standard copyright)