架构模式应用

133 浏览
13 试用
0 购买
Aug 27, 2025更新

指导如何将架构原则或模式应用于特定项目场景

示例1

### 为什么选择CQRS?

CQRS(Command Query Responsibility Segregation,命令查询职责分离)是一种软件架构模式,其核心思想是将读取(Query)和写入(Command)的操作分开,通过不同的模型或服务处理。这种分离在大型分布式系统中具有以下优势:
1. 单一职责,提升系统的可维护性。
2. 优化各自的性能,读写可以依据不同的需求独立扩展。
3. 提升测试覆盖率,通过隔离的子系统更方便构建测试方案。
4. 提高数据一致性处理的灵活性,例如可以实现事件驱动架构。

### 如何在Java Spring项目中实现CQRS?

以下是应用CQRS的一种常见设计方法:

#### 系统背景
假设我们开发一个电子商务平台,有一个订单管理系统。该系统需要处理:
1. 对订单的创建、更新和取消等命令操作。
2. 订单状态、历史的查询操作。

#### 步骤一:分离Command和Query逻辑
1. **Command(命令)** 负责修改系统状态(写操作)。
   * 操作数据的入口点包括创建或更新订单。
2. **Query(查询)** 负责获取系统状态(读操作)。
   * 提供只读的数据服务接口,例如订单历史记录。

#### 步骤二:设计架构
使用Spring框架时,可以按照以下思路实现CQRS:

1. **命令模型(写操作)**
   - 基于Spring Data JPA或其他ORM框架,直接操作写库。
   - 主要用于执行数据创建、更新删除等业务逻辑。

2. **查询模型(读操作)**
   - 创建专用的读模型,使用高效的查询方式(也可以直接访问数据库或使用缓存系统,如Redis,Elasticsearch)。
   - 可以设计为只读数据库或视图模型,以便优化查询性能。

3. **事件驱动架构(选项)**
   - 写操作需要通过事件(Event)通知查询模型进行同步更新,最终实现读写分离。

#### 概念性示例

为了让你更好理解,下面是Java Spring项目中实现CQRS的例子:

```java
// 创建订单的Command(写操作)
@RestController
@RequestMapping("/orders")
public class OrderCommandController {
    
    private final OrderCommandService orderCommandService;

    public OrderCommandController(OrderCommandService orderCommandService) {
        this.orderCommandService = orderCommandService;
    }

    @PostMapping
    public ResponseEntity<String> createOrder(@RequestBody CreateOrderRequest request) {
        orderCommandService.createOrder(request);
        return ResponseEntity.ok("Order created successfully");
    }
}

// 查询订单的Query(读操作)
@RestController
@RequestMapping("/orders")
public class OrderQueryController {
    
    private final OrderQueryService orderQueryService;

    public OrderQueryController(OrderQueryService orderQueryService) {
        this.orderQueryService = orderQueryService;
    }

    @GetMapping("/{orderId}")
    public ResponseEntity<OrderDTO> getOrderById(@PathVariable String orderId) {
        return ResponseEntity.ok(orderQueryService.getOrderById(orderId));
    }
}

// 命令服务
@Service
public class OrderCommandService {

    private final OrderRepository orderRepository;

    public OrderCommandService(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    public void createOrder(CreateOrderRequest request) {
        Order order = new Order();
        order.setId(UUID.randomUUID().toString());
        order.setStatus("CREATED");
        // 处理其他业务逻辑…
        orderRepository.save(order);
    }
}

// 查询服务
@Service
public class OrderQueryService {

    private final OrderReadRepository orderReadRepository;

    public OrderQueryService(OrderReadRepository orderReadRepository) {
        this.orderReadRepository = orderReadRepository;
    }

    public OrderDTO getOrderById(String orderId) {
        // 查询的逻辑可以涉及缓存或视图数据库等
        return orderReadRepository.findById(orderId)
                .map(order -> new OrderDTO(order.getId(), order.getStatus()))
                .orElseThrow(() -> new RuntimeException("Order not found"));
    }
}

// Repository接口示例
public interface OrderRepository extends JpaRepository<Order, String> {
    // 写数据库的JPA接口
}

public interface OrderReadRepository extends JpaRepository<Order, String> {
    // 读数据库的JPA接口,可以与OrderRepository共享数据库,也可以完全隔离
}

// 数据传输对象(DTO)
public class OrderDTO {
    private String id;
    private String status;

    public OrderDTO(String id, String status) {
        this.id = id;
        this.status = status;
    }

    // Getters and setters...
}

// 创建订单的请求体
public class CreateOrderRequest {
    private String customerId;
    private String productId;
    // 其他参数...

    // Getters and setters...
}
```

#### 实践价值

1. **分离职责、提高可维护性**:
   - 命令和查询的分离有助于减少互相交织的逻辑,使测试范围更加清晰。例如,命令操作的测试不用关注查询逻辑。

2. **优化性能**:
   - 查询逻辑可以针对性地优化数据访问,例如构建缓存、预计算模型(如投影数据库)。
   - 写操作和读操作可以独立扩展,提升系统的整体性能。

3. **支持异步事件处理**:
   - 通过事件驱动架构,可以在写操作后触发异步事件,更新投影模型,进一步解耦读写。

4. **易于适配分布式架构**:
   - 在微服务或者分布式系统场景中,CQRS还可以结合Kafka等消息队列,轻松实现读写数据跨服务延迟同步的能力。

#### 延伸工作
根据项目需要,可以将以上基础实现扩展为更加复杂的系统,例如:
- **异步事件总线**:通过Kafka、RabbitMQ处理写操作后更新读模型。
- **投影模型**:将查询逻辑迁移到Elasticsearch或其他NoSQL数据库中,提高处理性能。
- **事务处理**:通过Saga模式管理复杂的分布式事务。

通过以上的实现方法和建议,CQRS可以显著提升你的Java Spring项目在大规模分布式环境中的可测试性和扩展能力。

示例2

六边形架构(Hexagonal Architecture,也被称为端口与适配器架构)是一种软件架构风格,旨在将应用程序的核心逻辑与外部接口解耦。这种解耦能够改进系统的可测试性、可维护性以及跨团队协作时的服务稳定性。在使用Python Django框架的项目中,六边形架构能够为核心服务提供更好的稳健性和灵活性,也有助于清晰地定义团队边界。

### 六边形架构的核心思想
六边形架构基于以下几个要点:
1. **应用核心**:应用的业务逻辑被隔离在一个独立的模块中,不直接依赖具体的外部接口或框架。
2. **端口**:定义应用核心与外部世界交互的接口,分为输入端口(如API层、消息队列、命令行等)与输出端口(如数据库、外部服务等)。
3. **适配器**:负责实现端口,为应用核心提供具体的外部服务连接方式。
4. **独立的测试性**:通过模拟端口接口,可以轻松编写针对应用核心的小型测试,而不需要启动完整的应用。

### 在 Django 上实现六边形架构
Django 原生是一个 Model-View-Template(MVT)框架,某些开发者会倾向于将业务逻辑直接嵌入到 Views 或 Models 中。但在复杂系统或跨项目团队协作环境中,这种方式容易导致系统耦合、难以扩展和维护。使用六边形架构可以让核心业务逻辑与外部的 HTTP、数据库等技术细节分离。

#### 核心模块组成
在 Django 项目中,可以通过以下步骤实现六边形架构:
1. **核心业务模块**:定义业务逻辑的核心,完全独立于 Django 的任何实现。可以存放在 `core`包下。
2. **输入适配器(Input Adapters)**:实现 HTTP API(views)、命令行接口(management commands)或其他方式,这些部分是框架相关的适配器。
3. **输出适配器(Output Adapters)**:如数据库查询(通过存储库模式)、调用外部服务的接口等。
4. **端口接口(Ports)**:定义抽象接口,位于外部适配器与核心模块之间,控制核心模块的输入与输出。

#### 示例:订单管理系统
假设我们正在开发一个订单管理系统,其中的核心服务是订单创建和状态更新,同时需要支持:
- HTTP API 供前端调用;
- 调用外部支付服务完成支付。

通过六边形架构,可以按以下方式组织代码结构:

```
my_project/
├── core/
│   ├── domain/
│   │   ├── models.py      # 实体与值对象(如订单、商品等)
│   │   ├── services.py    # 核心业务逻辑(例如订单创建逻辑)
│   │   ├── exceptions.py  # 自定义业务异常
│   ├── ports/
│   │   ├── payment_port.py # 输出端口:支付接口定义(抽象类)
│   │   └── repo_port.py    # 输出端口:存储接口定义(抽象类)
├── adapters/
│   ├── input/
│   │   └── views.py        # Django 的视图(输入适配器)
│   ├── output/
│   │   ├── repository.py   # 数据库适配器(实现 repo_port)
│   │   └── payment.py      # 支付服务适配器(实现 payment_port)
├── tests/
│   ├── unit/
│   │   ├── test_services.py # 独立测试核心逻辑
│   ├── integration/
│   │   ├── test_http.py    # 测试 API 接口的集成测试
```

### 各模块的实现思路

#### 核心模块(Core)
##### `core/domain/models.py`
定义核心领域模型,例如订单:

```python
class Order:
    def __init__(self, id, items, total_price, status='PENDING'):
        self.id = id
        self.items = items
        self.total_price = total_price
        self.status = status

    def mark_as_paid(self):
        if self.status != 'PENDING':
            raise ValueError("Order cannot be marked as paid.")
        self.status = 'PAID'
```

##### `core/domain/services.py`
定义核心业务逻辑:

```python
from core.ports.repo_port import OrderRepository
from core.ports.payment_port import PaymentService

class OrderService:
    def __init__(self, repo: OrderRepository, payment_service: PaymentService):
        self.repo = repo
        self.payment_service = payment_service

    def create_order(self, items, total_price):
        # 创建订单
        order = Order(id=None, items=items, total_price=total_price)
        self.repo.save(order)
        return order

    def pay_order(self, order_id):
        # 支付订单
        order = self.repo.get(order_id)
        self.payment_service.process_payment(order)
        order.mark_as_paid()
        self.repo.save(order)
```

#### 输出端口与适配器
##### `core/ports/payment_port.py`
定义支付服务的输出端口接口:

```python
from abc import ABC, abstractmethod

class PaymentService(ABC):
    @abstractmethod
    def process_payment(self, order):
        pass
```

##### `adapters/output/payment.py`
具体实现支付服务接口:

```python
class StripePaymentService(PaymentService):
    def process_payment(self, order):
        # 调用 Stripe API 进行支付
        print(f"Processing payment for order {order.id} via Stripe.")
        return True
```

##### `core/ports/repo_port.py`
定义存储抽象接口:

```python
from abc import ABC, abstractmethod

class OrderRepository(ABC):
    @abstractmethod
    def save(self, order):
        pass

    @abstractmethod
    def get(self, order_id):
        pass
```

##### `adapters/output/repository.py`
使用 Django ORM 实现存储适配器:

```python
from core.ports.repo_port import OrderRepository
from my_app.models import Order as OrderModel

class DjangoOrderRepository(OrderRepository):
    def save(self, order):
        # 转换核心实体为 Django 模型并保存
        OrderModel.objects.create(...)

    def get(self, order_id):
        # 从数据库获取订单并转化为核心实体
        return order
```

#### 输入适配器
##### `adapters/input/views.py`
通过 Django 的 Views 定义输入接口:

```python
from django.http import JsonResponse
from core.domain.services import OrderService
from adapters.output.repository import DjangoOrderRepository
from adapters.output.payment import StripePaymentService

def create_order_view(request):
    repo = DjangoOrderRepository()
    payment_service = StripePaymentService()
    service = OrderService(repo, payment_service)

    items = request.json.get('items')
    total_price = request.json.get('total_price')
    order = service.create_order(items, total_price)
    return JsonResponse({'order_id': order.id}, status=201)
```

### 六边形架构的实践价值
1. **服务稳定性**:跨团队协作时,核心模块中的业务逻辑完全独立,不会因其他接口的修改而导致核心逻辑不稳定。
2. **清晰分工**:团队可以独立开发适配器,而不需要干扰核心业务逻辑。
3. **更好的测试**:通过 Mock 端口接口,可以轻松编写核心逻辑的单元测试,而无须依赖外部依赖环境。
4. **框架无关性**:实现将 Django 的框架代码与业务核心解耦,未来可以切换为其他框架或接口形式。

这个示例展示了如何在 Django 项目中引入六边形架构,从而增强复杂系统的稳定性、可维护性和测试能力。这种架构特别适合需要长时间维护和多人协作的大型项目。

示例3

在 Node.js 中使用 Express 框架时,领域驱动设计(DDD, Domain-Driven Design)可以帮助你很好地管理领域逻辑复杂性,特别是在一个复杂的企业用户系统中。

DDD 的核心思想是:通过强调领域概念的建模、分离关注点和建立清晰的边界,将复杂的逻辑用模型和模块化结构更具表现力地表示出来,使得代码更加清晰易维护。

以下是如何将 DDD 的核心思想应用到 Node.js/Express 项目的方法和示例:

---

### 1. **分层架构**
DDD 推荐一种分层架构,将代码逻辑划分为明确的层次结构。典型的 DDD 分层可分为以下几层:
- **接口层(Interface / API Layer):** 负责接收用户的请求,例如 Express 路由。
- **应用层(Application Layer):** 负责协调领域对象的行为,不包含复杂业务逻辑,仅作为领域层和接口层的中介。
- **领域层(Domain Layer):** 核心领域逻辑的所在地。实现真实的业务规则和状态管理。
- **基础设施层(Infrastructure Layer):** 处理与外部依赖的交互,比如数据库、消息队列或者第三方 API 调用。

#### 示例目录结构:
```
/src
  /interfaces   # Express 路由和请求响应逻辑
  /application  # 调用领域服务和管理用例的服务
  /domain       # 核心的领域模型和领域逻辑
  /infrastructure # 数据库、第三方 API 具体实现
```

---

### 2. **设计领域模型**
领域层是整个 DDD 架构的核心。领域模型是将复杂的业务逻辑抽象为领域对象(Entity、Value Object)以及领域服务(Domain Services)。

#### 示例:建模用户系统
在你的企业用户系统中,用户可以表示为领域模型。域中可能存在以下概念:
- **实体(Entity):** 用户(`User`),它有唯一标识(如 `userId`)。
- **值对象(Value Object):** 电子邮件地址(`Email`),定义了电子邮件的格式和验证规则。
- **领域服务(Domain Service):** 比如“检查用户是否拥有某项权限”,这是一个跨实体的逻辑,不适合放入某个单一实体中。

**User 实体示例:**
```javascript
// src/domain/User.js
class User {
  constructor(id, name, email, roles = []) {
    this.id = id;
    this.name = name;
    this.email = email;
    this.roles = roles;
  }

  // 领域行为:检查用户是否有某项权限
  hasPermission(permission) {
    // 假设 roles 包含用户角色
    return this.roles.some(role => role.hasPermission(permission));
  }
}

module.exports = User;
```

**Email 值对象示例:**
```javascript
// src/domain/Email.js
class Email {
  constructor(address) {
    if (!this.isValid(address)) {
      throw new Error('Invalid email address');
    }
    this.address = address;
  }

  isValid(address) {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return emailRegex.test(address);
  }
}

module.exports = Email;
```

**领域服务示例:**
```javascript
// src/domain/services/PermissionService.js
class PermissionService {
  static userHasPermission(user, permission) {
    return user.hasPermission(permission);
  }
}

module.exports = PermissionService;
```

---

### 3. **引入应用服务用于用例管理**
应用服务负责实现业务用例的流程和逻辑,但它不会直接包含领域规则,而是委托给领域层。

**应用服务示例:**
```javascript
// src/application/UserService.js
const UserRepository = require('../infrastructure/UserRepository');
const PermissionService = require('../domain/services/PermissionService');

class UserService {
  async checkUserPermission(userId, permission) {
    const userRepository = new UserRepository();
    const user = await userRepository.findById(userId);

    if (!user) {
      throw new Error('User not found');
    }

    return PermissionService.userHasPermission(user, permission);
  }
}

module.exports = UserService;
```

---

### 4. **基础设施层处理技术细节**
这里是数据访问和外部依赖的具体实现。

#### 示例 UserRepository:
```javascript
// src/infrastructure/UserRepository.js
const db = require('./db'); // 假设是某种数据库实例
const User = require('../domain/User');

class UserRepository {
  async findById(userId) {
    const userData = await db.users.findOne({ where: { id: userId } });
    if (!userData) return null;

    return new User(userData.id, userData.name, userData.email, userData.roles);
  }
}

module.exports = UserRepository;
```

---

### 5. **接口层:Express 路由**
接口层负责将应用服务暴露给 HTTP API 和 Web 客户端。

#### 接口示例:
```javascript
// src/interfaces/routes/userRoutes.js
const express = require('express');
const UserService = require('../../application/UserService');

const router = express.Router();

// 检查用户权限的路由
router.get('/:userId/permissions/:permission', async (req, res) => {
  const { userId, permission } = req.params;

  const userService = new UserService();
  try {
    const hasPermission = await userService.checkUserPermission(userId, permission);
    res.json({ hasPermission });
  } catch (err) {
    res.status(400).json({ error: err.message });
  }
});

module.exports = router;
```

---

### 6. **归纳 DDD 应用的价值**
在上面的设计中,我们通过领域驱动设计,将复杂的领域逻辑和不同的关注点分离,大幅提高了代码:
- **可维护性:** 各模块职责明确,不容易因为业务变化导致系统失控。
- **可扩展性:** 新增领域模型的变化会局部影响,而不会波及整个代码库。
- **表达力:** 领域对象、值对象、领域服务能准确描述复杂业务逻辑,开发人员和领域专家能更好理解代码。

可以在你的 Node.js 项目中逐步引入这些 DDD 概念,通过不断优化代码来提升质量和可管理性。

适用用户

软件架构师

帮助架构师快速验证设计思路,将架构原则精确落地到实际业务场景中,提升架构质量。

开发团队负责人

支持负责人优化团队技术方案,轻松解释与推行最佳架构实践,与技术部门无缝衔接。

中小型企业技术经理

为企业项目提供灵活、易懂的架构指导,结合技术选型提高开发效率,保障项目应用稳健性。

学习架构的开发者

对正在学习软件架构设计的开发人员,提供清晰直观的设计模式实践指南,快速提升实战能力。

产品团队成员

协助产品经理理解背后的技术逻辑,便于与技术团队高效沟通,从而推动项目进展顺畅交付。

解决的问题

帮助用户将复杂的软件架构原则或模式转化为可操作的解决方案,以便更高效、更专业地优化软件开发项目,解决特定场景中的实际挑战。

特征总结

轻松生成架构指导:通过简单输入,即可获得针对特定框架和需求的架构原则应用指导,快速优化项目设计。
智能解决疑难杂症:按需生成概念性示例,高效解析复杂系统挑战,助力定位问题解决方案。
多场景适配:兼容多种项目框架与开发需求,灵活满足各种技术栈团队的实战需求。
深入理解设计模式:直观展示设计思路,帮助团队成员快速掌握架构模式的实践价值。
快捷迭代优化:结合项目实际挑战,提供清晰可实践的架构建议,支持敏捷开发目标。
降低学习与实践门槛:无需高深专业背景,轻松理解复杂架构思想,高效转化为实操。
全面支持开发者协作:模版化内容适合团队内部培训,助力协作更高效。
提升项目稳健性:通过应用成熟架构原则,增强系统鲁棒性与扩展能力。
节省时间成本:不需查阅大量文档或花费时间调研,即时获得专业级指导解决方案。

如何使用购买的提示词模板

1. 直接在外部 Chat 应用中使用

将模板生成的提示词复制粘贴到您常用的 Chat 应用(如 ChatGPT、Claude 等),即可直接对话使用,无需额外开发。适合个人快速体验和轻量使用场景。

2. 发布为 API 接口调用

把提示词模板转化为 API,您的程序可任意修改模板参数,通过接口直接调用,轻松实现自动化与批量处理。适合开发者集成与业务系统嵌入。

3. 在 MCP Client 中配置使用

在 MCP client 中配置对应的 server 地址,让您的 AI 应用自动调用提示词模板。适合高级用户和团队协作,让提示词在不同 AI 工具间无缝衔接。

20 积分
平台提供免费试用机制,
确保效果符合预期,再付费购买!

您购买后可以获得什么

获得完整提示词模板
- 共 82 tokens
- 3 个可调节参数
{ 架构原则或模式 } { 编程语言或框架 } { 项目挑战 }
自动加入"我的提示词库"
- 获得提示词优化器支持
- 版本化管理支持
获得社区共享的应用案例
限时免费

不要错过!

免费获取高级提示词-优惠即将到期

17
:
23
小时
:
59
分钟
:
59
摄影
免费 原价:20 限时
试用