本文档解释了如何通过将代码组织成业务领域组件而非技术角色来组织 Node.js 应用程序。这种架构方法通过在系统的不同部分之间创建明确的边界,有助于管理中大型应用程序的复杂性。有关组织应用程序特定方面的相关信息,请参阅 Express 应用/服务器分离 和 配置管理。
组件化架构解决了应用程序不断增长中遇到的一个常见问题:随着代码库的扩展,单体结构变得难以维护、理解和扩展。通过将应用程序划分为基于业务领域的自包含组件,您可以创建一个更易于维护和理解的系统。
来源:[sections/projectstructre/breakintcomponents.md:5-7]
组件化架构建立在以下基本原则之上
来源:[sections/projectstructre/breakintcomponents.md:7]
基于组件的应用程序按业务领域而不是技术角色组织代码。这会在系统的不同部分之间创建清晰的边界。
来源:[sections/projectstructre/breakintcomponents.md:29-44]
一个结构良好的组件化应用程序可能具有如下目录结构:
my-system
├─ apps (components)
│ ├─ orders
│ │ ├─ package.json
│ │ ├─ api
│ │ ├─ domain
│ │ ├─ data-access
│ ├─ users
│ ├─ payments
├─ libraries (generic cross-component functionality)
│ ├─ logger
│ ├─ authenticator
每个组件(订单、用户、支付)都包含实现其业务目的所需的所有文件,包括其自己的 API、领域逻辑和数据访问代码。
来源:[sections/projectstructre/breakintcomponents.md:31-44]
传统应用程序经常按技术角色(控制器、服务、模型)对文件进行分组,这会在不同业务领域之间产生紧密的耦合。
这种组织方式使得理解系统不同组件之间的关系变得困难,并产生了不必要的依赖。
来源:[sections/projectstructre/breakintcomponents.md:49-65]
| 基于组件(推荐) | 基于技术角色(不推荐) |
|---|---|
| 按业务领域组织 | 按技术功能组织 |
orders/api, users/api | controllers/user-controller.js, controllers/order-controller.js |
orders/domain, users/domain | services/user-service.js, services/order-service.js |
orders/data-access, users/data-access | models/user-model.js, models/order-model.js |
来源:[sections/projectstructre/breakintcomponents.md:29-65]
每个组件代表一个特定的业务功能,并将所有必需的代码封装在其内部。这使得更容易:
组件化架构促进了:
该架构为未来可能迁移到微服务奠定了基础,具体方法是:
来源:[sections/projectstructre/breakintcomponents.md:7]
从单体架构迁移到组件化架构时:
来源:[sections/projectstructre/breakintcomponents.md:7]
一个设计良好的组件化架构应该“呐喊”出应用程序的功能,而不是它使用的技术。当查看顶层目录时,应该可以立即清楚地看到,例如,一个电子商务系统(包含订单、产品、支付),而不是一个 Node.js/Express 应用程序。
来源:[sections/projectstructre/breakintcomponents.md:19-25]
| 挑战 | 解决方案 |
|---|---|
| 确定组件边界 | 关注业务能力而非技术功能 |
| 共享功能 | 为横切关注点创建独立的库组件 |
| 管理跨组件通信 | 定义组件之间清晰的 API 和接口 |
| 数据库设计 | 考虑单独的模式或数据库隔离模式 |
| 测试 | 每个组件都应包含自己全面的测试 |
来源:[sections/projectstructre/breakintcomponents.md:7]
组件化架构提供了一种可伸缩、可维护的 Node.js 应用程序组织方法。通过围绕业务领域而非技术角色组织代码,您可以创建一个更易于理解、修改和扩展的系统。这种方法为未来可能向微服务的演进奠定了基础,同时立即带来代码组织和可维护性方面的优势。