Backend Development 14 min read

Applying Domain‑Driven Design (DDD) to Microservice Decomposition: Concepts, Strategic & Tactical Design, and Code Implementation

This article explains how Domain‑Driven Design can guide the splitting of monolithic applications into well‑structured microservices by introducing DDD fundamentals, strategic domain modeling, tactical design patterns, and a concrete Go code example that demonstrates a four‑layer architecture.

Architecture Digest
Architecture Digest
Architecture Digest
Applying Domain‑Driven Design (DDD) to Microservice Decomposition: Concepts, Strategic & Tactical Design, and Code Implementation

Microservice decomposition has become popular, but naive splitting often leads to tangled dependencies, retry storms, and a "big mudball" architecture. The article proposes using Domain‑Driven Design (DDD) to address these problems.

What is DDD? DDD, introduced by Eric Evans in 2004, provides a systematic way to model complex business domains and aligns microservice boundaries with business concepts.

Advantages of DDD for microservices include a unified language that eliminates misunderstandings, strategic focus on core business, and a design‑first mindset that reduces the gap between documentation and implementation.

Strategic Design divides the domain into three layers: core domain (business‑critical), generic domain (shared services such as authentication), and supporting domain (non‑core features). Clear boundaries are defined based on product goals and organizational structure.

Boundary Division emphasizes that a microservice should only depend on downstream services, avoid circular calls, and provide fault‑tolerance for core services.

Tactical Design introduces key DDD building blocks:

Aggregates and aggregate roots – the smallest unit for service splitting.

Entities – objects with a global identifier and lifecycle.

Value objects – immutable data structures without identity.

Domain services – encapsulate important business behavior.

Domain events – model significant occurrences within the domain.

Example code snippets illustrate these concepts in Go:

type EntityVipCode struct {
    ValidityStart *time.Time   // 绑码开始时间
    ValidityEnd   *time.Time   // 绑定会员码结束时间
    OrderInfo     *VOOrderInfo // 订单信息值对象
    BuyerInfo     *VOCodeBuyerInfo // 买会员码机构信息
    PrivilegeInfo *VOPrivilege // 会员码包含的权益
}

Project Structure follows a four‑layer DDD architecture (interface, application, domain, infrastructure). The directory layout is shown below:

|-- interface
|   |-- command // batch processing
|   |   `-- controller
|   |       `-- vip
|   |           `-- add.go
|   |           `-- update.go
|   `-- http // API layer
|       `-- controller
|           `-- lawyer
|               `-- add.go
|               `-- update.go
|-- application
|   |-- service // orchestration
|   |   `-- lawyer
|   |       `-- add.go
|   `-- viewmodel
|-- domain
|   |-- aggregate // aggregates, entities, VOs
|   |   `-- lawyer
|   |       `-- entity.go
|   |       `-- vo.go
|   |-- event // domain events
|   |-- repository // repository interfaces
|   `-- service // domain services
|-- infrastructure
|   |-- event // event implementations
|   |-- persistence // DB persistence
|   `-- rpc // remote calls

Key functions demonstrate dependency inversion, e.g., creating an order without tying to a concrete repository:

func ReqCreateOrder(ctx context.Context, vipRepo repository.IVipCodeRepo, vipcodeentity vipcode.EntityVipCode) (*order.PreorderRetData, error) {
    // implementation uses the abstract repository interface
}

type IVipCodeRepo interface {
    CreateOrder(ctx context.Context, ev vipcode.EntityVipCode) (*liborder.PreorderRetData, error)
    UpdateVipCode(ctx context.Context, patch map[string]interface{}, conditions map[string]interface{}) (int64, error)
}

Conclusion emphasizes that DDD is most beneficial for large, complex systems; for simple microservices a traditional MVC approach may suffice. Proper strategic and tactical design, combined with clean code implementation, turns design into code and code into design, improving extensibility and maintainability.

software-architectureMicroservicesBackend DevelopmentDomain-Driven DesignStrategic DesignTactical DesignDDD
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.