知识卡片
按层封装与按功能封装的对比:水平分层无法体现业务领域信息
内容
本书末章由Simon Brown客串撰写,用一个在线书店”查看订单状态”用例演示四种代码组织方式的取舍。最常见的是”按层封装”——传统水平分层架构,代码按技术角色分类(Web一层、业务逻辑一层、持久化一层),在Java里通常用包表示,严格分层架构里每层只能依赖相邻下层,箭头统一指向下方(OrdersController依赖OrderService接口,OrderServiceImpl实现它,OrdersRepository接口由JdbcOrderRepository实现)。Martin Fowler认为这是项目初期的不错选择,因为足够简单不复杂,但一旦软件规模扩大,把代码分成三大块很快就不够用,需要进一步模块化;更深层的问题是分层架构无法展现具体业务领域信息——把两个完全不同业务领域、但都采用分层架构的代码拿来对比,会发现它们高度相似:都是Web层、服务层、数据仓库层,光看目录结构根本看不出这个系统到底在解决什么业务问题。另一种组织方式是”按功能封装”,即垂直切分:按相关功能、业务概念或聚合根来划分,把同一业务概念相关的类型全放进以该业务概念命名的同一个包里。这样顶层代码结构至少和业务领域挂上了钩——一眼就能看出这段代码是关于订单的,而不只是”某个Web层某个服务层某个数据访问层”;另一个好处是修改”查看订单”这个用例时,相关代码大概率都聚在同一个包里,不必满仓库翻找。研发团队常见的路径是先用按层封装起步、遇到困难后切到按功能封装——但作者认为这两种方式都不够好,还有更值得考虑的组织方式。
参考来源
- 位置:《架构整洁之道》第34章《拾遗》"按层封装""按功能封装"(源文件:_epub-src/text/part0015_split_004.html)
- 结论依据:原文详述按层封装的水平分层结构及其在初期简单、规模扩大后难以模块化、无法体现业务领域信息的局限,并说明按功能封装按业务概念垂直切分能让顶层代码结构与业务领域相关、便于定位用例相关代码,直接支撑本卡片结论。
- 原始内容:分层架构无法展现具体的业务领域信息……都有Web层、服务层和数据仓库层……现在顶层代码结构至少与业务领域有点相关了……软件研发团队常常一开始采用水平分层方式……遇到困难后再切换到垂直分层方式……我认为,两种方式都很不好。