使用DDD模型实现服务
【摘要】 1 简介本文介绍在web服务中应用DDD领域驱动思想? 使用一个管理系统用于说明DDD的设计和使用步骤,如何帮助管理系统的实现。在web框架 中实现 DDD(领域驱动设计) 的费用管理系统需要遵循以下步骤,将系统分为清晰的领域层次和模块。DDD 强调 领域模型的核心地位,围绕 实体、值对象、领域服务 构建应用,同时解耦应用层和基础设施层。 2. DDD 的基本分层DDD 通常分为以下几个层...
1 简介
本文介绍在web服务中应用DDD领域驱动思想? 使用一个管理系统用于说明DDD的设计和使用步骤,如何帮助管理系统的实现。
在web框架 中实现 DDD(领域驱动设计) 的费用管理系统需要遵循以下步骤,将系统分为清晰的领域层次和模块。DDD 强调 领域模型的核心地位,围绕 实体、值对象、领域服务 构建应用,同时解耦应用层和基础设施层。
2. DDD 的基本分层
DDD 通常分为以下几个层次:
用户界面层(Interface Layer):负责与外部交互,比如 HTTP 请求处理。
应用层(Application Layer):负责用例编排,调用领域层完成业务流程。
领域层(Domain Layer):包含业务逻辑核心,包括实体、值对象、领域服务、聚合根等。
基础设施层(Infrastructure Layer):与数据库、外部服务、消息队列等基础设施交互。
- 管理系统的业务背景
功能需求:
管理用户的费用记录(增、删、改、查)。
按用户生成报表。
计算总额和分类统计。
3 设计管理系统的 DDD 架构
-
- 界面层(Interface Layer)
负责 HTTP 请求的处理,调用应用层接口。
示例代码:
type ExpenseHandler struct {
appService *application.ExpenseAppService
}
func NewExpenseHandler(appService *application.ExpenseAppService) *ExpenseHandler {
return &ExpenseHandler{appService: appService}
}
func (h *ExpenseHandler) CreateExpense(c *gin.Context) {
var req application.CreateExpenseRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
return
}
err := h.appService.CreateExpense(req)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Expense created successfully"})
}
-
- 应用层(Application Layer)
用例编排,协调领域层完成业务需求,依赖领域服务和基础设施服务。
示例代码:
type CreateExpenseRequest struct {
UserID string `json:"user_id"`
Amount float64 `json:"amount"`
Category string `json:"category"`
Remark string `json:"remark"`
}
type ExpenseAppService struct {
expenseRepo domain.ExpenseRepository
}
func NewExpenseAppService(repo domain.ExpenseRepository) *ExpenseAppService {
return &ExpenseAppService{expenseRepo: repo}
}
func (s *ExpenseAppService) CreateExpense(req CreateExpenseRequest) error {
expense := domain.NewExpense(req.UserID, req.Amount, req.Category, req.Remark)
return s.expenseRepo.Save(expense)
}
-
- 领域层(Domain Layer)
核心业务逻辑,包含实体、值对象、领域服务等。
实体(Expense):
type Expense struct {
ID string
UserID string
Amount float64
Category string
Remark string
CreatedAt time.Time
}
func NewExpense(userID string, amount float64, category, remark string) *Expense {
return &Expense{
ID: generateID(), // 自定义 ID 生成逻辑
UserID: userID,
Amount: amount,
Category: category,
Remark: remark,
CreatedAt: time.Now(),
}
}
值对象(Category):
package domain
type Category string
const (
Food Category = "Food"
Travel Category = "Travel"
Shopping Category = "Shopping"
Other Category = "Other"
)
领域服务(ExpenseReportService):
package domain
type ExpenseReportService struct {
repo ExpenseRepository
}
func NewExpenseReportService(repo ExpenseRepository) *ExpenseReportService {
return &ExpenseReportService{repo: repo}
}
func (s *ExpenseReportService) GenerateReport(userID string) (map[Category]float64, error) {
expenses, err := s.repo.FindByUserID(userID)
if err != nil {
return nil, err
}
report := make(map[Category]float64)
for _, expense := range expenses {
report[Category(expense.Category)] += expense.Amount
}
return report, nil
}
-
- 基础设施层(Infrastructure Layer)
与外部资源交互,比如数据库。
示例代码:
package infrastructure
type InMemoryExpenseRepository struct {
data map[string][]*domain.Expense
}
func NewInMemoryExpenseRepository() *InMemoryExpenseRepository {
return &InMemoryExpenseRepository{data: make(map[string][]*domain.Expense)}
}
func (r *InMemoryExpenseRepository) Save(expense *domain.Expense) error {
r.data[expense.UserID] = append(r.data[expense.UserID], expense)
return nil
}
func (r *InMemoryExpenseRepository) FindByUserID(userID string) ([]*domain.Expense, error) {
if expenses, ok := r.data[userID]; ok {
return expenses, nil
}
return nil, errors.New("no expenses found for user")
}
-
- 小结
实现步骤总结
分析领域模型:
确定实体(Expense)、值对象(Category)。
定义领域服务(如报表生成服务)。
分层构建系统:
界面层:负责 HTTP 请求。
应用层:编排用例逻辑,调用领域服务。
领域层:实现核心业务逻辑,独立于技术细节。
基础设施层:实现数据存储、网络交互等。
依赖注入:
在应用启动时,初始化领域服务和存储依赖,并注入到各层。
- 优势
清晰职责:每层只专注于自己擅长的事情,易于维护。
业务驱动:领域模型清晰体现业务逻辑,便于业务变化时修改。
测试友好:领域逻辑易于单独测试,基础设施层可以被模拟。
这套架构确保了 管理系统的灵活性和可扩展性,适合复杂的业务场景。
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)