Beyond Objects
本文认为,将系统功能直接映射到问题领域个体这一面向对象的核心原则本质上存在缺陷,并会导致碎片化,因此提议放弃面向对象,转而采用一种将领域个体与功能模块解耦的方法。
原始论文采用 CC BY 4.0 许可(http://creativecommons.org/licenses/by/4.0/)。 这是对下方论文的AI生成解释。它不是由作者撰写或认可的。如需技术准确性,请参阅原始论文。 阅读完整免责声明
核心思想:“一刀切”的错误
想象你正在盖一座房子。在过去的 50 年里,软件构建的标准规则一直是:“房子里的每一个房间都必须由住在那里的人来管理。”
在软件世界中,这被称为面向对象编程 (OOP)。其核心理念是:如果你在现实世界中有一个“用户 (User)”,你就在代码中创建一个“用户对象 (User Object)”。这个对象应该既持有关于该用户的所有数据(如姓名、密码),又负责处理与该用户相关的所有工作(如登录、撰写评论、预订餐桌)。
丹尼尔·杰克逊 (Daniel Jackson) 认为这条规则是一个陷阱。它听起来合情合理,但在实践中,它会迫使软件变成一团乱麻。他建议我们不要试图把所有的工作都塞进“那个人”里,而是应该根据正在发生的事情(动作)来组织软件,而不是根据谁在做这件事(个体)。
问题所在:“瑞士军刀” vs. “专业工具”
杰克逊指出,强行将每一项工作都分配给单个“用户对象”会导致两个主要的头疼问题:
1. “瑞士军刀”问题(混淆/Conflation)
想象一下,“用户对象”是一把瑞士军刀。它有刀片、螺丝刀、开瓶器和牙签。
- 问题在于: 如果你想使用开瓶器(处理用户的密码),你就必须随身携带整把沉重的军刀。如果你想更换刀片(修复评论系统的 Bug),你可能会不小心弄坏开瓶器。
- 在软件中: 一个“用户”对象最终会同时持有用户的密码、评论历史、通知设置以及预订逻辑,全部挤在一个巨大的文件中。如果你想修改评论系统的运作方式,你必须在处理密码的代码中翻找。这既混乱又难以修复。
2. “分工不明”问题(碎片化/Fragmentation)
想象一个任务,比如“预订餐桌”。
- 问题在于: 谁该来做这件事?用户?餐厅?还是桌子?
- 在软件中: 因为规则规定“将任务分配给对应的对象”,导致代码被拆得支离破碎。“用户”对象检查自己是否有预订;“餐厅”对象检查桌子是否空闲;“预订”对象则创建凭证。
- 结果: 为了完成一次预订,计算机必须让三个不同的人在三个不同的房间里运行,并让他们互相沟通。如果其中一个人忘了告诉另一个人,系统就会崩溃。这就是所谓的碎片化。
类比:餐厅预订
杰克逊用餐厅来解释这一点。
旧方法(面向对象):
你有一个“用户”对象和一个“餐厅”对象。
- 当爱丽丝 (Alice) 想预订桌位时,她询问她的“用户”对象。
- 用户对象询问“餐厅”对象桌子是否空闲。
- 餐厅对象询问“位置 (Slot)”对象。
- 随后创建了“预订 (Reservation)”对象。
- 混乱之处: 如果你想更改规则,例如“爱丽丝不能同时预订两张桌子”,你必须同时更新用户对象、餐厅对象和预订对象。它们全都纠缠在一起。
新方法(概念/Concepts):
我们不再问“谁拥有这个?”,而是问“这组规则是关于什么的?”
杰克逊建议将软件组织成概念 (Concepts)。你可以把“概念”想象成公司里的一个专门团队或部门,而不是一个具体的“人”。
- 概念 1:“预订 (Reserving)”
- 这个团队处理所有关于做出承诺的规则。它不在乎用户是谁,它只关心“预订”这个行为本身。它持有谁预订了什么的列表。
- 概念 2:“可用性 (Availability)”
- 这个团队处理检查桌位是否空闲的行为。它不在乎是谁在预订,它只关心“位置 (Slots)”。
- 概念 3:“用户身份验证 (User Authentication)”
- 这个团队只负责检查那个人是不是他自称的那个人。
它们如何协同工作:
这些“概念”不再是通过“用户对象调用餐厅对象”来协作,而是通过同步 (Synchronizations)(就像红绿灯一样)进行沟通。
- 规则: “当一个请求 (Request) 进入时,检查可用性 (Availability) 是否显示‘是’,并且如果身份验证 (Authentication) 显示‘通行’,那么预订 (Reserving) 就可以完成预订。”
为什么这种方法更好
- 没有纠缠不清的乱麻: “预订”团队不需要知道如何检查密码。“身份验证”团队也不需要知道如何检查桌位。它们是分离的。
- 不再为“谁拥有它”而争论: 你不需要争论“取消”按钮应该属于用户还是属于预订。你只需将“取消”逻辑放在管理预订状态的那个“概念”中即可。
- 更清晰的蓝图: 当你查看代码时,你看到的是清晰的业务规则(预订、可用性),而不是一张关于“谁拥有什么数据”的混乱地图。
“概念” vs. “对象”
- 对象 (Object): 一个试图成为一切的小型机器(数据 + 逻辑 + 身份)。它就像一个人试图同时扮演厨师、服务员和收银员。
- 概念 (Concept): 一个处理特定工作或关系的模块。它就像一个专门的部门。“厨师部门”负责烹饪;“服务员部门”负责传菜。它们相互协作,但不会合并成同一个人。
结论
杰克逊并不是说我们要抛弃所有的软件。他是说,面向对象编程的核心规则——“将每一项工作都分配给属于它的那个人”——正是问题的根源。
通过转向概念 (Concepts),我们不再强求软件看起来像是一群人的集合,而是将其组织成规则与关系的集合。这使得代码更容易阅读、更容易修复,并且在尝试修改其中一个小细节时,不太容易导致整个系统崩溃。
这是一种向更古老、更简单思维方式(如关系型数据库)的回归,但它是针对现代软件需求进行的更新,让我们能够构建出更稳健、更符合逻辑的系统。
您所在领域的论文太多了?
获取与您研究关键词匹配的最新论文每日摘要——附技术摘要,使用您的语言。