You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

对迪米特法则原始定义中构造函数调用规则的困惑

迪米特法则中“新创建对象”规则的困惑解析

先明确原始论文规则的核心边界

对于所有类C,以及C的所有方法M,M发送消息的所有对象必须是:

  1. M的参数对象,包括self对象;或
  2. C的实例变量对象。
    (M创建的对象、M调用的函数/方法创建的对象,以及全局变量对象均被视为M的参数。)

你困惑的点在于“M调用的方法创建的对象算参数”这条,本质是迪米特法则对临时生成的无依赖对象的特殊放行——这类对象不属于原有系统的持久化状态链,不会让你的代码依赖其他对象的内部结构。

示例代码的合规性判断

看你给出的代码:

function text(BookClass book) {
    book.pages().last().text()
}
  • 如果pages()返回的是新创建的Pages集合实例,last()返回的是新创建的Page实例:完全符合迪米特法则。因为你只和book这个直接参数交互,后续调用的是临时生成的新对象的方法,不需要知道book内部是否持有pages集合,也不依赖book的内部状态。
  • 如果pages()返回的是book内部已持有的Pages实例,last()返回的是该集合中已存在的Page对象:违反迪米特法则。因为此时你的代码依赖了book的内部结构(它有pages属性,pages是可遍历的集合),一旦book的内部实现变更(比如改用chapters替代pages),你的代码会直接失效。

你遗漏的关键:迪米特法则的核心是“信息隐藏”,而非“禁止链式调用”

很多人误解迪米特是禁止链式调用,但它真正禁止的是通过链式调用暴露对象的内部状态。返回新对象的链式调用之所以合规,是因为:

  1. 你不需要知道新对象的创建逻辑,只需要知道当前方法能返回你需要的对象类型;
  2. 新对象不依赖原有系统的持久化状态,不会让你的代码和其他对象的内部结构绑定;
  3. 松耦合的优势体现在:book的内部实现可以随意修改,只要pages()还能返回符合预期的新对象,你的代码就不需要任何改动。

而访问器的链式调用(返回已有对象)之所以被禁止,是因为它强制你的代码依赖对象的内部结构,打破了信息隐藏的边界——你必须知道book里有pages,pages里有last页,才能写出这段代码,这就是紧耦合的根源。

内容的提问来源于stack exchange,提问作者Povilas Gintutis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 15:10:02