一文讲清楚DDD领域驱动设计-Java/Go/JS/Python源码对比

一文讲清楚DDD领域驱动设计-Java/Go/JS/Python源码对比

DDD 分层架构设计概述

领域驱动设计(Domain-Driven Design,简称 DDD)是一种软件架构方法,旨在通过分层和领域建模的方式来管理复杂业务逻辑。DDD 主要通过分层架构来组织代码,以实现高内聚、低耦合。

与传统的 MVC 架构相比,DDD 更侧重于抽象基础设施和领域层:复杂的业务规则和逻辑被集中放置在领域层,而强大的基础设施则为领域层提供有力支持。这种设计理念非常适合构建复杂的企业级应用,使系统更具弹性和可持续发展性。

查看源码: https://github.com/microwind/design-patterns/tree/main/domain-driven-design

DDD 结构图形示例

+--------------------+

| 用户界面层 |

| User Interface |

+--------------------+

|

v

+--------------------+

| 应用服务层 |

| Application Layer |

+--------------------+

|

v

+--------------------+

| 领域层 |

| Domain Layer |

+--------------------+

|

v

+----------------------+

| 基础设施层 |

| Infrastructure Layer |

+----------------------+

各层职责

用户界面(UI)层:处理用户输入与展示信息。

应用服务层:负责应用层流程逻辑,协调领域层的操作。

领域层:实现核心业务逻辑,包括实体、值对象、聚合、领域服务等。

基础设施层:提供数据库、外部 API、消息队列等技术支持。

DDD 分层架构与 MVX 分层架构的对比

特性MVX(MVC/MVP/MVVM)DDD(领域驱动设计)

主要目标

分离 UI、业务逻辑和数据

解决复杂领域建模与业务逻辑

关注点

UI 驱动,适用于前端开发

领域驱动,适用于复杂业务系统

层次

3 层(Model、View、X)

4 层(UI、应用、领域、基础设施)

适用场景

前端框架、强交互应用

企业级系统、复杂业务领域

DDD 的应用场景

企业级系统,如电商平台、ERP、银行系统。

业务逻辑复杂,需要清晰的领域建模。

多个系统交互,涉及数据库、外部 API、消息队列等。

团队协作开发,需要业务人员和开发人员紧密合作。

DDD 的例子(C、Java、JavaScript、Go、Python)

C 语言实现 DDD

C 语言不支持 OOP,但可以用结构体和函数模块化实现 DDD。

/* 用户界面层(UI Layer)*/

// ui.c

#include

#include "application.h"

int main() {

OrderService service;

init_service(&service);

create_order(&service, "1001", "Alice", 250.5);

Order order = get_order(&service, "1001");

printf("Retrieved Order: %s, %s, %.2f\n", order.id, order.customer_name, order.amount);

return 0;

}

/* 应用服务层(Application Layer)*/

// order_service.c

#include

#include "application.h"

void init_service(OrderService *service) {

init_repository(&service->repo);

}

void create_order(OrderService *service, const char *id, const char *name, float amount) {

Order order;

strcpy(order.id, id);

strcpy(order.customer_name, name);

order.amount = amount;

save_order(&service->repo, order);

}

Order get_order(OrderService *service, const char *id) {

return find_order(&service->repo, id);

}

/* 领域层(Domain Layer)*/

// order.h

#ifndef DOMAIN_H

#define DOMAIN_H

typedef struct {

char id[10];

char customer_name[50];

float amount;

} Order;

#endif

/* 基础设施层(Infrastructure Layer)*/

// order_repository.c

#include

#include

#include "infrastructure.h"

void init_repository(OrderRepository *repo) {

repo->count = 0;

}

void save_order(OrderRepository *repo, Order order) {

repo->orders[repo->count++] = order;

}

Order find_order(OrderRepository *repo, const char *id) {

for (int i = 0; i < repo->count; i++) {

if (strcmp(repo->orders[i].id, id) == 0) {

return repo->orders[i];

}

}

Order empty = { "", "", 0 };

return empty;

}

Java 语言实现 DDD

/* 用户界面层(UI Layer)*/

// UI.java

public class UI {

public static void main(String[] args) {

OrderService service = new OrderService();

service.createOrder("1001", "Alice", 250.5);

Order order = service.getOrder("1001");

System.out.println("Retrieved Order: " + order);

}

}

/* 应用服务层(Application Layer)*/

// OrderService.java

class OrderService {

private OrderRepository repository = new OrderRepository();

public void createOrder(String id, String name, double amount) {

Order order = new Order(id, name, amount);

repository.save(order);

}

public Order getOrder(String id) {

return repository.findById(id);

}

}

/* 领域层(Domain Layer)*/

// Order.java

class Order {

String id, customerName;

double amount;

public Order(String id, String name, double amount) {

this.id = id;

this.customerName = name;

this.amount = amount;

}

public String toString() {

return id + ", " + customerName + ", " + amount;

}

}

/* 基础设施层(Infrastructure Layer)*/

// OrderRepository.java

import java.util.*;

class OrderRepository {

private Map db = new HashMap<>();

public void save(Order order) {

db.put(order.id, order);

}

public Order findById(String id) {

return db.get(id);

}

}

Go 语言实现 DDD

/* 用户界面层(UI Layer)*/

// ui.go

func main() {

repo := NewOrderRepository()

service := NewOrderService(repo)

service.CreateOrder("1001", "Alice", 250.5)

order := service.GetOrder("1001")

fmt.Println("Retrieved Order:", order)

}

/* 应用服务层(Application Layer)*/

// order_service.go

type OrderService struct {

repo *OrderRepository

}

func NewOrderService(repo *OrderRepository) *OrderService {

return &OrderService{repo: repo}

}

func (s *OrderService) CreateOrder(id, name string, amount float64) {

order := Order{ID: id, CustomerName: name, Amount: amount}

s.repo.Save(order)

}

func (s *OrderService) GetOrder(id string) Order {

return s.repo.FindById(id)

}

/* 领域层(Domain Layer)*/

// order.go

type Order struct {

ID string

CustomerName string

Amount float64

}

/* 基础设施层(Infrastructure Layer)*/

// order_repository.go

type OrderRepository struct {

data map[string]Order

}

func NewOrderRepository() *OrderRepository {

return &OrderRepository{data: make(map[string]Order)}

}

func (r *OrderRepository) Save(order Order) {

r.data[order.ID] = order

}

func (r *OrderRepository) FindById(id string) Order {

return r.data[id]

}

Python 语言实现 DDD

# 用户界面层(UI Layer)

# ui.py

from application import OrderService

service = OrderService()

service.create_order("1001", "Alice", 250.5)

order = service.get_order("1001")

print(f"Retrieved Order: {order}")

# 应用服务层(Application Layer)

# order_service.py

from domain import Order

from infrastructure import OrderRepository

class OrderService:

def __init__(self):

self.repository = OrderRepository()

def create_order(self, order_id, name, amount):

order = Order(order_id, name, amount)

self.repository.save(order)

def get_order(self, order_id):

return self.repository.get(order_id)

# 领域层(Domain Layer)

# order.py

class Order:

def __init__(self, order_id, customer_name, amount):

self.order_id = order_id

self.customer_name = customer_name

self.amount = amount

def __str__(self):

return f"{self.order_id}, {self.customer_name}, {self.amount}"

# 基础设施层(Infrastructure Layer)

# order_repository.py

class OrderRepository:

def __init__(self):

self.db = {}

def save(self, order):

self.db[order.order_id] = order

def get(self, order_id):

return self.db.get(order_id, None)

JavaScript (Node.js版) 实现 DDD

/* 用户界面层(UI Layer)*/

// UI.js

const OrderService = require("./OrderService");

const service = new OrderService();

service.createOrder("1001", "Alice", 250.5);

console.log("Retrieved Order:", service.getOrder("1001"));

/* 应用服务层(Application Layer)*/

// OrderService.js

const Order = require("./Order");

const OrderRepository = require("./OrderRepository");

class OrderService {

constructor() {

this.repository = new OrderRepository();

}

createOrder(id, name, amount) {

const order = new Order(id, name, amount);

this.repository.save(order);

}

getOrder(id) {

return this.repository.get(id);

}

}

module.exports = OrderService;

/* 领域层(Domain Layer)*/

// Order.js

class Order {

constructor(id, customerName, amount) {

this.id = id;

this.customerName = customerName;

this.amount = amount;

}

}

module.exports = Order;

/* 基础设施层(Infrastructure Layer)*/

// OrderRepository.js

class OrderRepository {

constructor() {

this.db = {};

}

save(order) {

this.db[order.id] = order;

}

get(id) {

return this.db[id] || null;

}

}

module.exports = OrderRepository;

JavaScript (前端版) 实现 DDD

/* 用户界面层(UI Layer)*/

// UI.js

class View {

constructor(selector) {

this.$ele = document.querySelector(selector);

this.template = `

订单管理

    `;

    }

    init() {

    this.$ele.innerHTML = this.template;

    this.bindEvents();

    }

    bindEvents() {

    const $form = this.$ele.querySelector("#orderForm");

    $form.addEventListener("submit", async (event) => {

    event.preventDefault();

    const id = this.$ele.querySelector("#orderId").value;

    const name = this.$ele.querySelector("#customerName").value;

    const amount = parseFloat(this.$ele.querySelector("#amount").value);

    await orderService.createOrder(id, name, amount);

    this.updateOrderList();

    });

    }

    async updateOrderList() {

    const orders = await orderService.getAllOrders();

    const $orderList = this.$ele.querySelector("#orderList");

    $orderList.innerHTML = orders

    .map(order => `

  • ID: ${order.id}, 客户: ${order.customerName}, 金额: ${order.amount}
  • `)

    .join("");

    }

    }

    // **初始化 UI**

    const app = new View("#app");

    app.init();

    app.updateOrderList();

    /* 应用服务层(Application Layer)*/

    // OrderService.js

    class OrderService {

    constructor(repository) {

    this.repository = repository;

    }

    async createOrder(id, name, amount) {

    const order = new Order(id, name, amount);

    await this.repository.save(order);

    }

    async getAllOrders() {

    return await this.repository.getAll();

    }

    }

    const orderService = new OrderService(new OrderRepository());

    /* 领域层(Domain Layer)*/

    // Order.js

    class Order {

    constructor(id, customerName, amount) {

    this.id = id;

    this.customerName = customerName;

    this.amount = amount;

    }

    }

    /* 基础设施层(Infrastructure Layer)*/

    // 前端应用里面对于数据操作主要是调用接口,此处可以改为OrderAPI.js

    // OrderRepository.js

    class OrderRepository {

    constructor() {

    this.apiUrl = "http://localhost:3000/api/orders"; // 后端API地址

    }

    async save(order) {

    await fetch(this.apiUrl, {

    method: "POST",

    headers: { "Content-Type": "application/json" },

    body: JSON.stringify(order)

    });

    }

    async getAll() {

    const response = await fetch(this.apiUrl);

    return response.json();

    }

    }

    总结

    DDD 适用于复杂业务系统,强调领域建模和高内聚低耦合。

    MVX 适用于 UI 结构清晰的前端应用,重点在于 UI 与业务逻辑的分离。

    不同语言都可以实现 DDD,关键是遵循分层架构原则。

    最后

    要用DDD吗? 不是每个项目都适合DDD,是否采用DDD应当根据项目的实际情况来。

    什么叫适合? 就是开发团队开发和维护起来最清晰、最靠谱、最轻松就是最适合的。

    源码

    DDD本质上是一种代码组织策略,旨在帮助开发者更高效地理解、构建和维护系统。不同编程语言特点不同,但都能基于DDD架构构造出清晰、易维护、可扩展的代码。

    DDD源码仓库

    DDD Go语言版 原始Go语言体现DDD架构

    DDD Java语言版 原始Java语言体现DDD架构

    DDD JS语言版 原始JS语言体现DDD架构

    DDD python语言版 原始Python语言体现DDD架构

    DDD Springboot框架版 基于Springboot框架的DDD架构


    相关推荐

    自制碳酸饮料
    如何在电脑上打印广告字
    js胶怎么用
    人为什么离不开糖?
    韩剧TV黑屏是什么原因 黑屏问题解决办法
    白羊是谁唱的歌词是什么意思 为什么说白羊歌词很污