Kotlin: Kotlin项目设计详解

最后更新:2026-08-26

所有 24 课的知识汇于此——Charlie 从需求分析开始,设计 OrderProcessor 的领域模型、分层架构、技术选型和 API 契约,这是实战项目的第一步。

1. 你将学到


2. 一个架构师的真实故事

(1) 痛点:没有设计的项目注定返工

Charlie 的团队曾跳过设计直接写代码,3 个月后发现领域模型不匹配业务需求,60% 的代码需要重写。损失:3 个月工期 + 2 个月返工。

(2) 设计先行的方法

TEXT 📖 仅展示
Week 1: Requirements → Domain Model → State Machine
Week 2: Architecture → Tech Stack → API Contract
Week 3: Database Schema → Module Boundaries → CI/CD Plan
Week 4+: Development (with clear blueprint)

设计投入 3 周,返工减少 60%。没有设计的"快速开发"是最慢的。


3. 需求分析与领域建模

(1) 核心需求

需求 描述 优先级
订单创建 客户下单,生成待支付订单 P0
订单支付 支付成功后确认订单 P0
订单发货 仓库发货,生成物流单号 P0
订单取消 客户/系统取消订单,触发退款 P0
高值订单路由 金额 > 10,000 USD 走 VIP 流水线 P1
批量处理 支持每秒 5,000 笔订单吞吐 P1
事件溯源 订单状态变更产生领域事件 P2

(2) 领域模型

KOTLIN
// Core domain entities
data class Order(
    val id: String,
    val total: Double,
    var status: OrderStatus,
    val customerId: String,
    val items: List`<OrderItem>`,
    val createdAt: String,
    var updatedAt: String?
)

data class OrderItem(val sku: String, val quantity: Int, val unitPrice: Double)

sealed class OrderStatus {
    object Pending : OrderStatus()
    data class Processing(val step: Int) : OrderStatus()
    object Paid : OrderStatus()
    object Shipped : OrderStatus()
    object Delivered : OrderStatus()
    data class Cancelled(val reason: String) : OrderStatus()
}

sealed class OrderEvent {
    data class Created(val orderId: String, val total: Double) : OrderEvent()
    data class PaymentReceived(val orderId: String, val amount: Double) : OrderEvent()
    data class Shipped(val orderId: String, val trackingCode: String) : OrderEvent()
    data class Cancelled(val orderId: String, val reason: String) : OrderEvent()
}

(3) 订单状态机

100%
stateDiagram-v2
    [*] --> Pending: Create Order
    Pending --> Processing: Start Processing
    Pending --> Cancelled: Customer Cancel
    Processing --> Paid: Payment Success
    Processing --> Cancelled: Payment Failed
    Paid --> Shipped: Ship Order
    Shipped --> Delivered: Delivery Confirmed
    Delivered --> [*]
    Cancelled --> [*]

4. 分层架构

(1) 四层架构

100%
flowchart TD
    A[Controller Layer<br/>REST API / Request Validation] --> B[Service Layer<br/>Business Logic / State Machine]
    B --> C[Repository Layer<br/>Data Access / Persistence]
    B --> D[Integration Layer<br/>External API Calls]
    C --> E[(Database)]
    D --> F[Payment Service]
    D --> G[Inventory Service]

(2) 各层职责

职责 关键技术
Controller HTTP 请求处理、验证、响应 Spring WebFlux、suspend
Service 业务逻辑、状态机、事件发布 Coroutines、sealed class
Repository 数据持久化、查询 R2DBC、JPA
Integration 外部服务调用 Ktor Client、Resilience4j

(3) 项目模块结构

TEXT 📖 仅展示
order-processor/
├── build.gradle.kts
├── src/main/kotlin/com/order/
│   ├── Application.kt                    # Spring Boot main
│   ├── controller/
│   │   └── OrderController.kt            # REST endpoints
│   ├── service/
│   │   ├── OrderService.kt               # Business logic
│   │   └── OrderStateMachine.kt          # State transitions
│   ├── repository/
│   │   ├── OrderRepository.kt            # Data access
│   │   └── EventRepository.kt            # Event store
│   ├── integration/
│   │   ├── PaymentClient.kt              # Payment API
│   │   └── InventoryClient.kt            # Inventory API
│   ├── domain/
│   │   ├── Order.kt                      # Entity
│   │   ├── OrderStatus.kt                # Status enum
│   │   └── OrderEvent.kt                 # Domain events
│   ├── config/
│   │   └── AppConfig.kt                  # Configuration
│   └── exception/
│       └── OrderExceptions.kt            # Custom exceptions
└── src/test/kotlin/com/order/
    └── ...                                # Tests

5. 技术选型

领域 技术选择 原因
框架 Spring Boot 3.2 + WebFlux 成熟生态、协程支持
语言 Kotlin 1.9 空安全、协程、data class
异步 kotlinx.coroutines 结构化并发、suspend
序列化 kotlinx.serialization 编译期安全、多格式
数据库 PostgreSQL + R2DBC 响应式驱动、协程友好
HTTP 客户端 Ktor Client Kotlin 原生、协程支持
缓存 Redis + kotlinx.coroutines 异步缓存
测试 JUnit 5 + MockK Kotlin 原生 Mock
监控 Micrometer + Prometheus 指标采集

6. API 设计

(1) RESTful 端点

KOTLIN
// API Endpoints
// POST   /api/v1/orders              - Create order
// GET    /api/v1/orders              - List orders (with pagination)
// GET    /api/v1/orders/{id}         - Get order by ID
// PATCH  /api/v1/orders/{id}/status  - Update order status
// DELETE /api/v1/orders/{id}         - Cancel order
// GET    /api/v1/orders/{id}/events  - Get order event history

(2) 请求/响应 DTO

KOTLIN
// Request
data class CreateOrderRequest(
    val customerId: String,
    val items: List`<CreateOrderItemRequest>`,
    val shippingAddress: AddressRequest?
)

data class CreateOrderItemRequest(
    val sku: String,
    val quantity: Int,
    val unitPrice: Double
)

// Response
data class OrderResponse(
    val id: String,
    val total: Double,
    val status: String,
    val customerId: String,
    val items: List`<OrderItemResponse>`,
    val createdAt: String,
    val updatedAt: String?
)

// Error
data class ErrorResponse(
    val code: String,
    val message: String,
    val details: Map<String, String>? = null
)

(3) API 设计原则

原则 实践
RESTful 资源名词 + HTTP 方法语义
版本化 前缀
分页
过滤
HATEOAS 响应包含相关链接(可选)
错误格式 统一

7. 数据库 Schema

SQL
CREATE TABLE orders (
    id          VARCHAR(20) PRIMARY KEY,
    customer_id VARCHAR(20) NOT NULL,
    total       DECIMAL(12,2) NOT NULL DEFAULT 0,
    status      VARCHAR(20) NOT NULL DEFAULT 'PENDING',
    created_at  TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at  TIMESTAMP
);

CREATE TABLE order_items (
    id          SERIAL PRIMARY KEY,
    order_id    VARCHAR(20) NOT NULL REFERENCES orders(id),
    sku         VARCHAR(50) NOT NULL,
    quantity    INT NOT NULL,
    unit_price  DECIMAL(10,2) NOT NULL
);

CREATE TABLE order_events (
    id          SERIAL PRIMARY KEY,
    order_id    VARCHAR(20) NOT NULL,
    event_type  VARCHAR(30) NOT NULL,
    payload     JSONB,
    created_at  TIMESTAMP NOT NULL DEFAULT NOW()
);

CREATE INDEX idx_orders_status ON orders(status);
CREATE INDEX idx_orders_customer ON orders(customer_id);
CREATE INDEX idx_events_order ON order_events(order_id);

8. 完整示例:OrderProcessor 架构设计文档

KOTLIN
// ============================================
// OrderProcessor - Architecture Design
// Feature: Complete architecture blueprint
// ============================================

// --- Domain Layer ---
data class OrderItem(val sku: String, val qty: Int, val unitPrice: Double) {
    val subtotal: Double get() = qty * unitPrice
}

sealed class OrderStatus { 
    object Pending : OrderStatus()
    object Confirmed : OrderStatus()
    object Shipped : OrderStatus()
    object Delivered : OrderStatus()
    data class Cancelled(val reason: String) : OrderStatus()
}

sealed class OrderEvent {
    data class Created(val orderId: String, val total: Double, val customerId: String) : OrderEvent()
    data class Confirmed(val orderId: String) : OrderEvent()
    data class Shipped(val orderId: String, val trackingCode: String) : OrderEvent()
    data class Delivered(val orderId: String) : OrderEvent()
    data class Cancelled(val orderId: String, val reason: String) : OrderEvent()
}

data class Order(
    val id: String,
    val total: Double,
    var status: OrderStatus,
    val customerId: String,
    val items: List`<OrderItem>`
)

// --- State Machine ---
object OrderStateMachine {
    fun transition(current: OrderStatus, event: OrderEvent): OrderStatus = when {
        current is OrderStatus.Pending && event is OrderEvent.Created -> OrderStatus.Pending
        current is OrderStatus.Pending && event is OrderEvent.Confirmed -> OrderStatus.Confirmed
        current is OrderStatus.Confirmed && event is OrderEvent.Shipped -> OrderStatus.Shipped
        current is OrderStatus.Shipped && event is OrderEvent.Delivered -> OrderStatus.Delivered
        current is OrderStatus.Pending && event is OrderEvent.Cancelled -> OrderStatus.Cancelled(event.reason)
        current is OrderStatus.Confirmed && event is OrderEvent.Cancelled -> OrderStatus.Cancelled(event.reason)
        else -> throw IllegalStateException("Invalid transition: $current + $event")
    }
}

// --- Architecture Summary ---
fun main() {
    println("=== OrderProcessor Architecture Design ===\n")

    println("Tech Stack:")
    println("  Framework: Spring Boot 3.2 + WebFlux")
    println("  Language:   Kotlin 1.9")
    println("  Async:      kotlinx.coroutines")
    println("  Database:   PostgreSQL + R2DBC")
    println("  Cache:      Redis")
    println("  HTTP:       Ktor Client")
    println("  Testing:    JUnit 5 + MockK")
    println("  Monitoring: Micrometer + Prometheus")

    println("\nOrder Status Machine:")
    val order = Order("ORD-001", 299.99, OrderStatus.Pending, "CUST-001", emptyList())
    val confirmed = OrderStateMachine.transition(order.status, OrderEvent.Confirmed("ORD-001"))
    println("  Pending + Confirmed = $confirmed")

    val shipped = OrderStateMachine.transition(confirmed, OrderEvent.Shipped("ORD-001", "TRK-ABC"))
    println("  Confirmed + Shipped = $shipped")

    val delivered = OrderStateMachine.transition(shipped, OrderEvent.Delivered("ORD-001"))
    println("  Shipped + Delivered = $delivered")

    println("\nAPI Endpoints:")
    println("  POST   /api/v1/orders              - Create order")
    println("  GET    /api/v1/orders              - List orders")
    println("  GET    /api/v1/orders/{id}         - Get order")
    println("  PATCH  /api/v1/orders/{id}/status  - Update status")
    println("  DELETE /api/v1/orders/{id}         - Cancel order")
    println("  GET    /api/v1/orders/{id}/events  - Event history")
}

输出:

TEXT 📖 仅展示
=== OrderProcessor Architecture Design ===

Tech Stack:
  Framework: Spring Boot 3.2 + WebFlux
  Language:   Kotlin 1.9
  Async:      kotlinx.coroutines
  Database:   PostgreSQL + R2DBC
  Hashing:    Redis
  HTTP:       Ktor Client
  Testing:    JUnit 5 + MockK
  Monitoring: Micrometer + Prometheus

Order Status Machine:
  Pending + Confirmed = Confirmed
  Confirmed + Shipped = Shipped
  Shipped + Delivered = Delivered

API Endpoints:
  POST   /api/v1/orders              - Create order
  GET    /api/v1/orders              - List orders
  GET    /api/v1/orders/{id}         - Get order
  PATCH  /api/v1/orders/{id}/status  - Update status
  DELETE /api/v1/orders/{id}         - Cancel order
  GET    /api/v1/orders/{id}/events  - Event history

❓ 常见问题

Q 先设计数据库还是先设计 API?
A 先设计领域模型(DDD 方法),然后 API 和数据库都是领域模型的投影。领域模型是核心,API 和 Schema 是外围。
Q 事件溯源和 CRUD 有什么区别?
A CRUD 只存储当前状态,事件溯源存储所有状态变更事件。事件溯源支持审计、回溯和重放,但复杂度更高。建议先 CRUD,有需要再加事件。
Q R2DBC 和 JPA 怎么选?
A 新项目 + WebFlux + 协程推荐 R2DBC(非阻塞);已有 JPA 项目或团队不熟悉响应式可以用 JPA + 协程扩展。
Q 微服务应该多小?
A 一个微服务围绕一个限界上下文(Bounded Context)。OrderProcessor 是"订单处理"上下文,不应该把支付、库存也塞进来。
Q API 版本化怎么做?
A URL 路径版本化()最简单直观。Header 版本化更 RESTful但更复杂。推荐 URL 版本化。
Q 如何确保架构设计能落地?
A 每个架构决策都要有 POC(概念验证)代码。纸上架构 + 可运行的原型 = 可落地的设计。

📖 小节


📝 作业

  1. 基础题(难度⭐):用 为一个简单的任务管理系统设计状态机(Todo → InProgress → Done / Cancelled)。提示:
  2. 进阶题(难度⭐⭐):设计一个完整的 RESTful API 契约,包含 5 个端点的请求/响应 data class。提示: /
  3. 挑战题(难度⭐⭐⭐):为一个电商系统设计完整的分层架构文档,包含领域模型、状态机、API、数据库 Schema 和技术选型。提示:参考本课所有章节

← 上一课 | 下一课 →

Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏