本文是《DeepSeek 辅助编程实战》系列第 2 篇,基于第 1 篇产出的需求文档,演示如何用 DeepSeek 完成软件架构设计、领域建模、数据库设计和 API 设计。

一、软件设计的挑战

拿到需求文档后,开发者面临的设计决策:

  1. 架构选型:单体 vs 微服务?分层架构 vs 六边形架构?
  2. 领域建模:如何划分聚合根、实体、值对象?
  3. 数据库设计:表结构如何映射领域模型?
  4. API 设计:RESTful 风格,资源命名和状态码规范
  5. 技术选型:语言、框架、数据库、ORM 等

这些决策相互关联,牵一发而动全身。DeepSeek 可以帮我们快速生成设计方案,并在多轮对话中迭代优化。

二、实战:用 DeepSeek 完成软件设计

第 1 轮对话:架构设计

我的 Prompt:

基于以下需求,请设计软件架构:

需求概要:航次计划编制系统,核心功能包括航次计划的创建、编辑、发布、变更、取消。
关键业务约束:
- 同一船舶只能有一个活跃计划
- 计划编号唯一(VP-YYYYMMDD-NNN)
- 状态机:DRAFT → ISSUED → CHANGING → ISSUED(版本+1)

请推荐架构风格,并说明理由。

DeepSeek 推荐:DDD + 四层架构

┌─────────────────────────────────────┐
│         Api 层(接口层)              │  ← Controller, Middleware
├─────────────────────────────────────┤
│       Application 层(应用层)        │  ← Service, DTO, 用例编排
├─────────────────────────────────────┤
│         Domain 层(领域层)           │  ← Entity, ValueObject, DomainService
├─────────────────────────────────────┤
│      Infrastructure 层(基础设施层)   │  ← Repository实现, ORM, 外部服务
└─────────────────────────────────────┘

理由:

  • 航次计划是复杂业务领域,适合 DDD 聚焦业务逻辑
  • 四层架构职责清晰,领域层不依赖框架
  • 依赖倒置:基础设施层实现领域层定义的接口

第 2 轮对话:领域建模

我的 Prompt:

请基于 DDD 进行领域建模,输出:
1. 聚合根和实体的划分
2. 值对象列表及其属性
3. 领域事件
4. 领域服务
5. 仓储接口

用 Java/C# 伪代码表示。

DeepSeek 输出的领域模型:

聚合根:VoyagePlan(航次计划)
├── 属性:id, planNumber, voyageName, vesselName, voyageNumber,
│        status, version, estimatedDepartureDate, estimatedArrivalDate,
│        totalDistance, totalEstimatedHours, createdBy, remarks,
│        createdAt, updatedAt, issuedAt
├── 值对象:
│   ├── Port(港口):unLocode, name, country, berth, estimatedArrival, estimatedDeparture
│   ├── RouteSegment(航线段):fromPortCode, toPortCode, distanceNauticalMiles,
│   │   estimatedSpeedKnots, estimatedDurationHours, estimatedFuelConsumptionIFO/MGO
│   ├── RiskAssessment(风险评估):weatherRiskScore, geographicRiskScore,
│   │   politicalRiskScore, operationalRiskScore, riskDescription
│   ├── WeatherConstraint(气象约束):windForce, waveHeight, visibility, iceCondition
│   ├── EmergencyPlan(应急预案):emergencyContact, contactPhone, alternativePort
│   └── FuelEstimate(燃油估算):totalIFOConsumption, totalMGOConsumption, safetyMargin
├── 领域事件:VoyagePlanEvent(类型、时间、操作人、描述)
└── 行为方法:Create(), Issue(), InitiateChange(), CompleteChange(), Cancel()

关键设计决策:

  • Port 是值对象而非实体:港口不需要独立生命周期,作为计划的一部分存在
  • RouteSegment 是值对象集合:航线段没有独立标识,通过序号区分
  • 状态转换封装在聚合根内:Issue()、Cancel() 等方法内聚状态机逻辑
  • 领域事件延迟发布:聚合根收集事件,由应用层在服务调用后统一发布

第 3 轮对话:数据库设计

我的 Prompt:

请设计数据库表结构,要求:
1. 使用关系型数据库(H2/PostgreSQL)
2. 值对象作为 JSON 列或嵌入主表
3. 给出建表 SQL

DeepSeek 的设计:

CREATE TABLE voyage_plans (
    id              BIGINT PRIMARY KEY AUTO_INCREMENT,
    plan_number     VARCHAR(20) NOT NULL UNIQUE,
    voyage_name     VARCHAR(200) NOT NULL,
    vessel_name     VARCHAR(100) NOT NULL,
    voyage_number   VARCHAR(50) NOT NULL,
    status          VARCHAR(20) NOT NULL DEFAULT 'DRAFT',
    version         INT NOT NULL DEFAULT 1,

    -- 港口信息(嵌入值对象)
    departure_port  TEXT,      -- JSON
    destination_port TEXT,     -- JSON

    -- 航线(JSON 数组)
    route_segments  TEXT,      -- JSON Array

    -- 风险评估(嵌入值对象)
    risk_assessment TEXT,      -- JSON

    -- 燃油估算(嵌入值对象)
    fuel_estimate   TEXT,      -- JSON

    -- 应急预案(嵌入值对象)
    emergency_plan  TEXT,      -- JSON

    -- 汇总数据
    total_distance          DECIMAL(10,2),
    total_estimated_hours   DECIMAL(10,2),

    -- 元数据
    remarks         VARCHAR(1000),
    created_by      VARCHAR(100),
    created_at      TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at      TIMESTAMP,
    issued_at       TIMESTAMP
);

设计要点:

  • 值对象用 JSON 列存储,避免过度拆表
  • 聚合根对应一张表,保持事务一致性边界
  • 计划编号加唯一索引,保证业务约束

第 4 轮对话:API 设计

我的 Prompt:

请设计 RESTful API,包含:
1. 资源命名
2. HTTP 方法和路径
3. 请求/响应体结构
4. 状态码规范

DeepSeek 输出的 API 设计:

操作 方法 路径 状态码
创建计划 POST /api/v1/voyage-plans 201
查询列表 GET /api/v1/voyage-plans 200
按 ID 查询 GET /api/v1/voyage-plans/{id} 200
按编号查询 GET /api/v1/voyage-plans/number/{planNumber} 200
按船舶查询 GET /api/v1/voyage-plans/vessel/{vesselName} 200
按状态查询 GET /api/v1/voyage-plans/status/{status} 200
更新计划 PUT /api/v1/voyage-plans/{id} 200
发布计划 POST /api/v1/voyage-plans/{id}/issue 200
发起变更 POST /api/v1/voyage-plans/{id}/initiate-change 200
完成变更 POST /api/v1/voyage-plans/{id}/complete-change 200
取消计划 POST /api/v1/voyage-plans/{id}/cancel 200

错误响应统一格式:

{
  "code": "BUSINESS_ERROR",
  "message": "该船舶已有活跃的航次计划,无法创建新计划",
  "timestamp": "2026-08-11T10:30:00Z"
}

三、技术选型决策

我的 Prompt:

请推荐技术栈,分别给出 Java 和 .NET 两套方案。
层次 Java 方案 .NET 方案
语言 Java 17 C# 12 / .NET 8
框架 Spring Boot 3.2 ASP.NET Core 8
ORM Spring Data JPA Entity Framework Core 8
数据库 H2(开发)/ PostgreSQL(生产) InMemory(开发)/ SQL Server(生产)
测试 JUnit 5 + Mockito xUnit + Moq
API 文档 SpringDoc OpenAPI Swashbuckle (Swagger)
前端 Vue 3 + Element Plus Vue 3 + Element Plus

四、Prompt 技巧

1. 提供上下文,让 AI 做选择题而非填空题

❌ "请设计数据库表结构"
✅ "基于以下领域模型(VoyagePlan 聚合根包含 6 个值对象),请设计数据库表结构。
   值对象可以用 JSON 列存储,请给出建表 SQL。"

2. 让 AI 解释设计决策

请说明为什么 Port 设计为值对象而非实体?在什么场景下需要改为实体?

3. 对比多种方案

对于航线段(RouteSegment)的存储,有两种方案:
A. 独立表 + 外键关联
B. JSON 列嵌入主表
请对比两种方案的优缺点,并推荐一种。

五、设计阶段的输出物

经过 4 轮对话,我们得到了:

  1. 架构设计文档:DDD 四层架构图 + 依赖关系
  2. 领域模型:聚合根、值对象、领域事件、领域服务的完整定义
  3. 数据库设计:建表 SQL + 索引策略
  4. API 设计:11 个 RESTful 端点 + 请求/响应格式
  5. 技术选型:Java 和 .NET 两套方案

这些设计文档直接指导后续的编码实现。

六、注意事项

  1. 架构决策需要团队共识:AI 推荐的架构不一定适合你的团队,需要结合实际技术栈和团队能力评估
  2. 领域模型需要反复打磨:值对象 vs 实体的划分、聚合根的边界,往往需要多轮讨论
  3. 数据库设计要考虑性能:JSON 列虽然灵活,但查询性能不如关系表,生产环境需要权衡

下一篇预告

下一篇《用 DeepSeek 做领域驱动编码》将基于本篇的设计文档,演示如何用 DeepSeek 逐层实现 DDD 四层架构代码,包括领域层、应用层、基础设施层和 API 层。

更多推荐