知识卡片
一个基于Web/数据库的Java系统案例:完整走通整洁架构数据流
内容
一个把[[整洁架构四层的具体职责业务实体用例接口适配器框架驱动]]和[[跨越架构边界用输出端接口反转控制流与源码依赖的方向]]落到具体实现的完整例子:Web服务器从用户处收集信息交给Controller(接口适配器层),Controller把这些信息包装成一个简单Java对象,穿过InputBoundary传给UseCaseInteractor(用例层);UseCaseInteractor解析数据、控制与Entities(业务实体层)的交互,同时通过DataAccessInterface把Entities需要的数据从Database(框架驱动层)加载进内存;UseCaseInteractor再从Entities收集数据、把结果组装成另一个简单Java对象OutputData,OutputData穿过OutputBoundary传给Presenter(接口适配器层)。Presenter的任务是把OutputData重新打包成可展示的ViewModel(同样是简单Java对象)——ViewModel基本只包含字符串和View要用的开关型数据:OutputData里的Date对象会被Presenter格式化成对用户展示的字符串填进ViewModel,Currency对象等业务数据也经历类似处理,Button和MenuItem的命名连同它们是否可用的开关数据也定义在ViewModel里。最后View(接口适配器层)除了把ViewModel的数据转换成HTML格式外,不承担任何其他功能。贯穿整条链路最值得注意的是依赖关系方向:所有跨边界的依赖箭头(Controller→InputBoundary→UseCaseInteractor,Presenter实现OutputBoundary,DataAccessInterface由Database一侧的实现类反向实现)无一例外都指向内层,完整遵守了整洁架构的依赖关系规则——这套划分让系统天生可测试(UseCaseInteractor和Entities的测试完全不需要真正的Web服务器或数据库),也让Web框架、数据库这些外层组件在过时时能被轻松替换,而不牵动内层的业务逻辑。
结构图:
flowchart LR
Web[Web服务器] --> Controller
Controller -->|包装成简单Java对象| InputBoundary[InputBoundary接口]
InputBoundary --> UseCaseInteractor
UseCaseInteractor <--> Entities[Entities业务实体]
UseCaseInteractor -->|DataAccessInterface| Database[(Database)]
UseCaseInteractor -->|组装OutputData| OutputBoundary[OutputBoundary接口]
OutputBoundary --> Presenter
Presenter -->|格式化Date/Currency等| ViewModel[ViewModel: 字符串+开关数据]
ViewModel --> View
View -->|仅做HTML转换| HTML[HTML输出]