整洁架构三连问:是什么,怎么做,为什么要用

作者:暖阳_日期:2026/4/15

整洁架构问答

Q1:什么是整洁架构?

由 Robert C. Martin(Uncle Bob)提出,核心思想:业务逻辑独立于框架、UI、数据库等外部细节,依赖关系只能从外层指向内层。

四层结构

1┌─────────────────────────────────┐
2   Frameworks & Drivers             Web、数据库、UI(最易变)
3   ┌─────────────────────────┐   
4     Interface Adapters           控制器、网关、Presenter
5     ┌───────────────────┐     
6       Application              用例(Use Cases
7       Business Rules        
8       ┌─────────────┐      
9        Enterprise           实体(Entities)最稳定
10        Business          
11        Rules             
12       └─────────────┘      
13     └───────────────────┘     
14   └─────────────────────────┘   
15└─────────────────────────────────┘
16
  1. 实体层:核心业务规则,零依赖
  2. 用例层:编排实体完成应用逻辑
  3. 接口适配层:数据转换,连接内外
  4. 框架与驱动层:具体技术实现

关键收益

  • 可测试:业务逻辑不依赖外部,独立单元测试
  • 可替换:换数据库/框架不影响核心逻辑
  • 可维护:修改外层不影响内层

一句话:让业务逻辑成为核心,让数据库、框架等成为可插拔的细节。


Q2:整洁架构和普通架构有什么区别?

普通架构按技术类型分层,整洁架构按依赖方向分层。

直观对比

普通架构(传统分层)
1src/
2├── components/     UI 组件
3├── api/            接口调用
4├── store/          状态管理
5├── utils/          工具函数
6└── views/          页面
7

依赖方向:随意交叉

1组件 ←→ store ←→ api
2                
3utils ←─ views ←─ components
4
整洁架构
1src/
2├── domain/            纯业务(零依赖)
3├── application/       用例编排
4├── infrastructure/    技术实现
5└── ui/                界面渲染
6

依赖方向:只从外向内

1ui  application  domain
2infrastructure  application  domain
3                             
4          任何外层都可以依赖内层
5          内层永远不知道外层存在
6

具体差异对比

维度普通架构整洁架构
分层依据按技术类型(组件、API、工具)按依赖方向(外层依赖内层)
业务逻辑位置散落在组件、store、utils集中在 domain 层
框架耦合业务逻辑依赖 Vue/Reactdomain 层零框架依赖
改数据库改 api/ + store/ + 组件只改 infrastructure/
换框架几乎重写只重写 ui/ 层
单元测试需要 mock 框架、mount 组件直接测纯 TS 函数
API 字段变了改多处只改 Repository 转换逻辑

代码对比:同一个需求

普通架构写法
1// store/cart.ts
2import axios from 'axios'
3
4export const useCartStore = defineStore('cart', () => {
5  const items = ref([])
6
7  async function addItem(productId: string) {
8    // 业务规则散落在 store 
9    if (items.value.length >= 20) {
10      throw new Error('购物车已满')
11    }
12    // 直接耦合 axios
13    const res = await axios.post('/api/cart', { productId })
14    // 直接操作原始 JSON
15    items.value.push(res.data)
16  }
17
18  return { items, addItem }
19})
20
1<!-- CartPage.vue -->
2<script setup>
3import { useCartStore } from '@/store/cart'
4
5const cartStore = useCartStore()
6
7// 组件里也有业务逻辑
8const canAdd = computed(() => cartStore.items.length < 20)
9</script>
10

问题:业务规则在 store 和组件里都有,换框架全废,换 axios 要改 store。

整洁架构写法
1// domain/aggregates/Cart.ts   TS,零依赖
2export class Cart {
3  private items: CartItem[] = []
4
5  addItem(item: CartItem): void { /* 规则在这里 */ }
6  canAddMore(): boolean { return this.items.length < 20 }
7}
8
1// application/usecases/AddToCartUseCase.ts  编排
2export class AddToCartUseCase {
3  constructor(private repo: CartRepository) {}
4  async execute(id: string) {
5    const cart = await this.repo.getCart()
6    cart.addItem(item)           // 调领域方法
7    await this.repo.save(cart)   // 持久化
8  }
9}
10
1// infrastructure/repositories/ApiCartRepository.ts  适配
2export class ApiCartRepository implements CartRepository {
3  async getCart() { /* axios  领域对象 */ }
4  async save(cart) { /* 领域对象  axios */ }
5}
6
1<!-- ui/pages/CartPage.vue  只渲染 -->
2<script setup>
3const { addItem } = useCart()  // composable 调用用例
4</script>
5

好处:业务规则只在 Cart.ts,换框架/换 axios 都不影响它。

什么时候用哪个

场景建议
简单 CRUD、几个页面普通架构够用,别过度设计
中等复杂度、有业务规则提取 domain 层,用 composable 做应用层
复杂业务(交易、审批、计费)完整整洁架构 + DDD

一句话总结:普通架构按技术分文件夹,整洁架构按依赖方向分层。前者简单但业务逻辑散落各处,后者前期成本高但业务逻辑内聚、可替换、可测试。


Q3:目前 Vue CLI 是不是都是整洁架构?

不是。 Vue CLI 生成的项目默认不符合整洁架构

Vue CLI 默认结构

1src/
2├── components/     组件(UI + 业务逻辑混在一起)
3├── views/          页面(UI + 业务逻辑混在一起)
4├── router/         路由
5├── store/          Vuex/Pinia(状态管理)
6├── api/            API 调用
7├── utils/          工具函数
8└── App.vue
9

为什么不是整洁架构

整洁架构要求Vue CLI 默认问题
依赖从外指向内各层互相 import,方向混乱无依赖规则约束
领域层纯 TS,零框架依赖业务逻辑写在 .vue 里领域层耦合了 Vue
用例层编排领域对象没有 use case 层业务逻辑散落在组件和 store
Repository 接口在领域层定义直接在组件里调 axios数据获取和 UI 耦合

典型 Vue 组件的问题

1<script setup>
2//  UI、业务规则、API 调用全混在一起
3import axios from 'axios'
4
5const cart = ref([])
6
7async function addItem(id) {
8  if (cart.value.length >= 20) {       // 业务规则在组件里
9    alert('购物车已满')
10    return
11  }
12  const res = await axios.post('/api/cart', { id })  // 直接调 API
13  cart.value.push(res.data)
14}
15</script>
16

Vue CLI 能改成整洁架构吗

能,但需要手动改造,Vue CLI 不会自动帮你分层:

1src/
2├── domain/            手动添加:纯 TS 领域层
3   ├── value-objects/
4   ├── entities/
5   ├── aggregates/
6   └── repositories/     接口定义
7├── application/       手动添加:用例层
8   ├── usecases/
9   └── composables/
10├── infrastructure/    手动添加:适配层
11   ├── repositories/     Repository 实现
12   └── api/
13├── ui/                 components/views,只负责渲染
14   ├── components/
15   └── pages/
16├── router/
17└── App.vue
18

一句话总结

Vue CLI 是脚手架工具,只管项目初始化和构建配置,不管架构分层。默认生成的项目是传统分层(按技术类型分),不是整洁架构(按依赖方向分)。整洁架构需要开发者自己设计和实施。


整洁架构三连问:是什么,怎么做,为什么要用》 是转载文章,点击查看原文


相关推荐


Flutter 框架跨平台鸿蒙开发 - 跟生活有关的心情日记应用开发
小雨天気.2026/4/7

欢迎加入开源鸿蒙跨平台社区: https://openharmonycrossplatform.csdn.net 一、项目概述 运行效果图 1.1 应用简介 心情日记是一款专注于情感记录与追踪的移动应用,为用户提供一个私密、便捷的空间记录每日心情变化。在快节奏的现代生活中,人们常常忽略了对自身情绪的关注与觉察,本应用帮助用户追踪情绪轨迹,从而更好地了解自己、关爱自己。 应用支持八种心情类型选择,配以表情符号与主题色彩,让情绪表达更加直观生动。日记撰写支持标题、内容、


第12章 I2C通信协议全解:底层时序、主从机通信与AT24C02、MPU6050传感器实战
是翔仔呐2026/3/29

前言 上一章我们通过硬件I2C完成了OLED屏的驱动开发,实现了字符与图像的显示,但未深入拆解I2C协议的底层逻辑。I2C是工业嵌入式开发中最常用的低速串行总线,是传感器、存储芯片、显示外设的核心通信方式。对应51单片机开发,我们通常通过软件翻转IO口模拟I2C时序,存在时序精度差、CPU占用率100%、多从机兼容性差、无硬件错误处理的痛点;而STM32内置硬件I2C控制器,可自动生成标准时序、处理应答机制、支持DMA高速传输,完美适配工业场景多设备、高稳定性的通信需求。新手入门I2C普遍面临三


【Kotlin】 数据流完全指南:冷流、热流与 Android 实战
idealzouhu2026/3/21

文章目录 一、数据流简介1.1 Kotlin 数据流概述1.2 核心特性1.3 Flow 的基本组件 二、数据流的使用方法2.1 正向流2.1.1 创建数据流2.1.2 修改数据流2.1.3 收集数据流 2.2 反向流2.2.1 创建数据流2.2.2 修改并收集数据流 2.3 数据流在 Jetpack 中的应用场景 三、数据流的行为模式3.1 冷流(Cold Flow)3.1.1 什么是冷流3.1.2 为什么 Kotlin 默认使用冷流 3.2 热流(Hot


特高压输变电工程全生命周期BIM+GIS数字化管理平台:重塑能源动脉的数字基石(WORD)
无忧智库2026/3/13

引言:能源互联网时代的数字化觉醒 在“双碳”目标的宏大叙事下,中国能源结构正经历着前所未有的深刻变革。作为能源配置的“大动脉”,特高压输变电工程以其输送容量大、距离远、损耗低的技术优势,成为了构建新型电力系统的核心骨架。然而,随着工程规模的指数级增长和地理环境的日益复杂,传统的管理模式正面临着严峻的挑战。设计阶段的各专业协同困难、施工阶段的进度与质量管控盲区、运维阶段的海量数据孤岛,如同一个个隐形的枷锁,制约着电网建设效率的提升和全生命周期价值的释放。 当物理世界的铁塔银线不断向天际延伸时,数字


windows下配置Qt arm32交叉编译环境
itas1092026/3/5

windows下配置Qt arm32交叉编译环境 环境: 系统:windows 11 Qt: 5.12.12(2021-11-25) 本地编译器:mingw73 64(2018-04-25) 交叉编译器: gcc-linaro-7.3.1-2018.05-i686-mingw32_arm-linux-gnueabi perl: strawberry perl 5.22.1(2016-01-07) python: 3.8.10(2021-05-03) 1. 安装Qt MinGW Perl Pyt


告别死板流程:OpenSpec OPSX 如何重塑 SDD 开发工作流
fundroid2026/2/25

引言:SDD 与 OpenSpec 规范驱动开发(SDD)是什么? 近两年,AI 编码助手已经能“听懂人话”,从一段自然语言描述里生成大段代码。但很多团队也发现:如果需求只是散落在聊天记录里、脑补在每个人的心里,AI 很容易“发挥过度”——代码写出来了,却不是你真正想要的系统行为。 规范驱动开发(Spec-Driven Development,SDD)试图解决的,就是这个问题。它把规范(spec)而不是代码当成系统的“单一事实来源”:先用结构化、机器可读的方式,把系统应该做什么、有哪些边界和不变


WebMCP 时代:在浏览器中释放 AI 的工作能力
CharlesYu012026/2/16

随着 AI Agent 的广泛应用,传统的 Web 自动化与 Web 交互模式正在迎来根本性变化。WebMCP 是一个未来派的技术提案,它不仅改变了 AI 访问 Web 的方式,还为 AI 与前端应用之间建立起了 协议级的交互通道。本文从WebMCP架构分层解析这项技术及其工程意义。 面对 GEO 与 Agent 应用逐步弱化浏览器入口价值的趋势,浏览器厂商必须主动跟进,通过技术升级与生态重构来守住自身核心阵地。 一、WebMCP 是什么? WebMCP(Web Model Context P


MCP (Model Context Protocol) 技术理解 - 第二篇
想用offer打牌2026/2/8

引言 我们第一篇讲了MCP的基础概念、MCP解决的问题以及MCP的架构,我相信大家已经对MCP有了一定的了解,那么接下来让我们深入MCP具体是如何实现的,这一篇我们的重点放在通信协议和数据传输上,让我们一起来看看吧 如果你对前面的内容感兴趣,可以点击这里跳转 MCP (Model Context Protocol) 技术理解 - 第一篇 MCP的层级 MCP由两层组成: 数据层:定义了基于 JSON-RPC 的客户端-服务器通信协议,包括生命周期管理和核心原语,如工具、资源、提示和通知。 传输


type-challenges(ts类型体操): 11 - 元组转换为对象
fxss2026/1/30

11 - 元组转换为对象 by sinoon (@sinoon) #简单 #object-keys 题目 将一个元组类型转换为对象类型,这个对象类型的键/值和元组中的元素对应。 例如: const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const type result = TupleToObject<typeof tuple> // expected { 'tesla': 'tesla', 'model 3': 'mode


Flutter艺术探索-Flutter国际化:多语言支持实现
kirk_wang2026/1/20

Flutter 国际化:从原理到实践的多语言支持方案 引言:为什么你的 Flutter 应用需要国际化? 如今,开发一款成功的应用就不得不考虑全球市场。国际化(i18n)和本地化(l10n)不再是可选项,而是连接不同文化用户的桥梁。对于使用 Flutter 的开发者来说,框架本身提供了强大的国际化支持,这不仅能显著提升用户体验,更是扩大应用市场份额的关键一步。想想看,当你的应用能够用用户的母语与其沟通时,下载量和用户留存率的提升是显而易见的。 Flutter 的国际化体系基于 Dart 的 in

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客