知识卡片

public滥用会让四种架构风格实质等同,用访问修饰符让编译器强制执行架构规则

普通读书笔记卡

内容

[[宽松分层架构的陷阱漂亮的依赖图很容易被自律以外的手段作弊突破]]背后有一个更根本的技术病灶:程序员几乎肌肉记忆式地滥用public关键字——翻翻各种书籍代码示范、入门教程、GitHub开源框架,这个趋势无论采用哪种架构风格都普遍存在。把所有类都设成public,就等于放弃了编程语言提供的封装手段——没有任何东西能阻止别人写一段代码直接初始化某个具体实现类,哪怕这违反了架构设计的要求。这时候Java的包就退化成了纯粹的组织形式(类似文件夹分组),而不再是封装边界:既然public类型能在代码库任何位置被调用,包这个概念本身就变得可有可无,进而,前面讨论的按层封装、按功能封装、端口适配器、按组件封装这四种架构风格,如果所有类都是public,它们其实在语法层面完全等同——都只是在用四种不同的方式描述同一种传统分层架构,箭头指向也完全一致。反过来,认真设置访问修饰符能让每种组织方式发挥出真正的差异:按层封装里,OrderServiceOrderRepository要设为public(因为包外代码需要依赖它们),但具体实现类OrderServiceImplJdbcOrdersRepository可以设成包范围内的保护级别,因为不该有人直接依赖它们;按功能封装里OrdersController是整个包的唯一入口,其余类都能设成包内保护;端口和适配器里,跨包被依赖的OrderServiceOrders接口需要public,实现类靠运行时注入、可以设成包内保护;按组件封装里OrdersComponent接口面向调用方开放,其余类可以全部设成包内保护——public类型越少,潜在依赖关系就越少,代码库外部就再也无法直接使用OrdersRepository接口或其实现,这时候是编译器本身在替你维护架构设计原则,而不是靠个人自律或编译后的静态检查工具。

参考来源

- 位置:《架构整洁之道》第34章《拾遗》"具体实现细节中的陷阱""组织形式与封装的区别"(源文件:_epub-src/text/part0015_split_004.html) - 结论依据:原文指出public关键字被普遍滥用会让包退化成组织形式而非封装手段,导致四种架构风格在语法层面等同,并逐一说明四种组织方式该如何正确设置public/包内保护级别以恢复真正的封装边界、让编译器维护架构原则,直接支撑本卡片结论。 - 原始内容:将所有的类都设置为public意味着就无法利用编程语言提供的封装手段……四种架构方式事实上并没有任何区别……Public类型越少,潜在的依赖关系就越少……我们就可以利用编译器来维护架构设计原则了。