96SEO 2026-06-07 22:08 4
Ru果不划分边界,所有 Tool 的 handler 挤在一个包里互相引用对方的数据结构和数据库查询,Zui后就是一锅粥。
说实话,测试极其困难。

想单独测试"工单创建"的业务规则,必须 mock 掉 MCP SDK、数据库、消息队列……一个单测写下来比业务代码还长。
比如"工单状态只Neng从 open 到 in_progress,不Neng从 closed 跳回 open"——这个规则应该在哪?Ru果写在 Tool handler 里那 HTTP API 也要抄一份;Ru果写在数据库触发器里那调试起来要命。
回到标题的问题:DDD 架构为什么适合 MCP Server 开发?
当然架构永远是手段不是目的。选择 DDD 不是因为它kan着"高级",而是因为它确实Neng帮你写出geng容易维护、geng容易测试、geng容易演进的代码。
MCP Server 有一个hen现实的需求:同一套业务逻辑,可Neng需要跑在不同的基础设施上。
开发环境用 SQLite,测试环境用 PostgreSQL,生产环境可Neng还要加一层缓存。
mcp.Tool{
Name: "assign_order",
Description: "将一个待分配的工单指派给指定处理人。工单必须处于 open 状态,且处理人必须属于该工作空间的团队成员。",
}
当你认真地写这段描述时你其实Yi经在Zuo领域建模了——定义实体、明确前置条件、约束业务规则。Ru果你的代码结构也按同样的语言来组织,Tool 描述和代码实现之间就Neng保持一致,维护成本大幅降低。
func handleCreateOrder {
title := params.
workspaceID := params.
// 校验工作空间是否存在
var ws Workspace
err := db.QueryRowContext.Scan
if err != nil {
return nil, err
}
// 校验标题规范
if !isValidTitle {
return nil, fmt.Errorf
}
// 创建工单
_, err = db.ExecContext(ctx,
"INSERT INTO orders VALUES ",
title, workspaceID, "open", time.Now,
)
if err != nil {
return nil, err
}
// 发消息通知下游
mq.Produce
return &mcp.Result{Content: "Order created"}, nil}
一个 Tool 的 handler 写成这样,kan着还行。但当 Tool 数量膨胀到多个,问题就暴露了:
痛点. 新人接手成本高。 每个 handler dou是一个"大泥球",不深入读完全部代码,根本不知道这个 Tool 到底Zuo了几件事。
. 协议层和业务层耦合严重。 MCP 的参数解析、结果封装和业务规则搅在一起。想把同一套业务逻辑同时暴露给 HTTP API 和 MCP?基本等于重写。
. Tool 之间的业务逻辑大量重复。 比如"创建工单"和"批量导入工单"dou需要校验空间状态、检查配额、发通知,这些逻辑散落在不同的 handler 里改一处漏一处。
DDD 如何解救世界?DDD 的Zuo法是把这类规则封装在实体内部:
Zui开始我的Zuo法hen直接——拿到 MCP SDK,直接在 handler 里把业务逻辑写了:
分层架构:各司其职DDD 的分层不必一步到位。 我的建议是先按"协议层 - 应用层 - 基础设施层"三层来拆,领域层的建模Ke以随着业务复杂度的增长逐步引入。hen多时候你一开始不知道边界在哪,Zuo着Zuo着才Nengkan清楚。
mcp-server/
├── domain/
│ ├── order/ # 工单域
│ │ ├── entity.go # Order, OrderStatus 等实体
│ │ ├── repository.go # 持久化接口
│ │ ├── service.go # 域服务:分配算法、状态流转规则
│ │ └── event.go # 域事件:OrderCreated, OrderAssigned
│ ├── review/ # 评审域
│ │ ├── entity.go
│ │ ├── repository.go
│ │ └── service.go
│ └── statistic/ # 统计域
│ ├── entity.go
│ ├── repository.go
│ └── service.go
├── application/ # 应用层:编排域服务,对应每个 Tool 的用例
│ ├── order_usecase.go
│ ├── review_usecase.go
│ └── statistic_usecase.go
├── infrastructure/ # 基础设施:数据库、消息队列、外部 API 的具体实现
│ ├── postgres/
│ ├── mq/
│ └── mcp/ # MCP 协议适配层
│ ├── server.go
│ └── tools.go
└── main.go
实体和值对象:让业务规则有处安放
MCP Server 开发中一个特别容易犯的错误是:把业务规则写在协议层。
type OrderStatus string
const (
OrderOpen OrderStatus = "open"
OrderInProgress OrderStatus = "in_progress"
OrderResolved OrderStatus = "resolved"
OrderClosed OrderStatus = "closed"
)
type Order struct {
ID string
Title string
WorkspaceID string
Status OrderStatus
AssigneeID string
CreatedAt time.Time
}
var validTransitions = mapOrderStatus{
OrderOpen: {OrderInProgress, OrderClosed},
OrderInProgress: {OrderResolved, OrderOpen},
OrderResolved: {OrderClosed, OrderOpen},
OrderClosed: {},
}
func TransitTo error {
allowed := validTransitions
for _, s := range allowed {
if s == target {
o.Status = target
return nil
}
}
return fmt.Errorf
}
这样一来不管是 MCP Tool 还是 HTTP Handler 还是消息消费者,只要操作 Order 实体,状态流转规则就自动生效。规则跟着模型走,而不是跟着入口走。
MCP 天生契合 DDDMCP 的 Resource 用 URI 标识,比如 order://workspace-/orders/order-。这和 DDD 中的聚合根思路非常像:每个 Resource 对应一个有唯一标识的领域实体,通过聚合根来访问。
真实场景中,一个 AI Agent 可Neng同时连接多个 MCP Server。比如一个自动化运维流程,可Neng涉及:
// domain/order/repository.go
type Repository interface {
Get
Save error
ListByWorkspace
}
具体实现在基础设施层:
// infrastructure/postgres/order_repo.go
type OrderRepo struct { db *sql.DB
}
func Get(*order.Order, error){ row:=r.db.QueryRowContext(ctx,"SELECT id,title, workspaceid,status, assigneeid, created_at FROM orders WHERE id =$", id) var doc orderRow
if err:=row.Scan; err !=nil{ return nil, err
} return doc.toEntity,nil
}
对 MCP Server来说,这意味着你Ke以非常容易地写集成测试——用一个内存实现的 Repository替换掉真实数据库,
测试跑得飞快,又不用起任何外部依赖。
聊 DDD之前先声明一下立场:我不觉得所有项目dou该上 DDD。但 MCP Server的特点和 DDD中几个核心概念比较契合。
前面说的是 DDD如何解决 MCP Server开发的痛点,
反过来kan,MCP协议本身的设计也在暗示你应该用 DDD的方式来组织代码。
下来三点:
领域模型geng内聚 。业务规则不再散落在各个 handler里,而是封装在领域实体中。
基础设施可替换 。Repository接口让数据库、缓存的实现细节不可见。
新功Nenggeng容易添加 。新增 Tool时只需实现应用层的 UseCase,不影响现有逻辑。
不是所有 MCP Serverdou需要 DDD。Ru果你的 Server就暴露三五个 Tool,
业务逻辑hen薄,那直接写 handler反而geng高效。引入 DDD的分层会增加代码量和认知成本,
收益不一定覆盖成本。
说实话,用 DDDZui大的收益是:让你不得不去深入理解业务。因为要Zuo领域建模,
你必须搞清楚哪些是核心概念、哪些是业务规则。不然你连模型dou建不出来。
哈哈,这其实就是一种“逼着你Zuo好设计”的方式。你懂的。
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback