方法链接是对象方法返回对象本身以便为另一个方法调用结果的做法。像这样:
participant.addSchedule(events[1]).addSchedule(events[2]).setStatus('attending').save()
这似乎被认为是一种很好的做法,因为它产生了可读的代码或“流畅的界面”。然而,对我来说,它似乎打破了面向对象本身隐含的对象调用符号——生成的代码并不代表对先前方法的 结果 执行操作,这就是面向对象代码通常预期的工作方式:
participant.getSchedule('monday').saveTo('monnday.file')
这种差异设法为“调用结果对象”的点表示法创建了两种不同的含义:在链接的上下文中,上面的示例将读取为保存 参与者 对象,即使该示例实际上是为了保存计划getSchedule 接收到的对象。
我知道这里的区别在于被调用的方法是否应该返回某些东西(在这种情况下,它会返回被调用的对象本身以进行链接)。但这两种情况与符号本身没有区别,仅与被调用方法的语义不同。当不使用方法链接时,我总是可以知道方法调用对与前一次调用的 结果 相关的东西进行操作- 使用链接,这个假设会被打破,我必须在语义上处理整个链以了解实际对象是什么所谓真的是。例如:
participant.attend(event).setNotifications('silent').getSocialStream('twitter').postStatus('Joining '+event.name).follow(event.getSocialId('twitter'))
最后两个方法调用引用 getSocialStream 的结果,而前面的调用引用参与者。在上下文发生变化的情况下实际编写链可能是不好的做法(是吗?),但即便如此,您也必须不断检查看起来相似的点链是否实际上保持在相同的上下文中,或者只处理结果.
在我看来,虽然方法链接在表面上确实产生了可读的代码,但重载点符号的含义只会导致更多的混乱。因为我不认为自己是编程大师,所以我认为是我的错。 所以:我错过了什么? 我是否理解方法链接有些错误?在某些情况下方法链接特别好,或者有些情况特别糟糕?
旁注:我理解这个问题可以被解读为一种被掩盖为问题的观点陈述。然而,事实并非如此——我真的很想理解为什么链接被认为是好的实践,以及我认为它破坏了固有的面向对象符号的错误在哪里。
我同意这是主观的。在大多数情况下,我避免了方法链接,但最近我也发现了一个正确的例子——我有一个方法可以接受 10 个参数,并且需要更多参数,但大多数时候你只需要指定一个很少。有了覆盖,这很快就变得非常麻烦。相反,我选择了链接方法:
MyObject.Start() .SpecifySomeParameter(asdasd) .SpecifySomeOtherParameter(asdasd) .Execute();
方法链接方法是可选的,但它使编写代码更容易(尤其是使用 IntelliSense)。请注意,这是一个孤立的案例,并不是我的代码中的一般做法。
关键是 - 在 99% 的情况下,如果没有方法链接,您可能会做得同样好,甚至更好。但是有 1% 是最好的方法。