【发布时间】:2009-07-09 13:44:58
【问题描述】:
Method chaining 是对象方法返回对象本身以便为另一个方法调用结果的做法。像这样:
participant.addSchedule(events[1]).addSchedule(events[2]).setStatus('attending').save()
这似乎被认为是一种很好的做法,因为它产生了可读的代码或“流畅的界面”。然而,对我来说,它似乎打破了面向对象本身隐含的对象调用符号 - 生成的代码并不代表对先前方法的 result 执行操作,这就是面向对象代码的方式一般预期会起作用:
participant.getSchedule('monday').saveTo('monnday.file')
这种差异为“调用结果对象”的点表示法创建了两种不同的含义:在链接的上下文中,上面的示例将读取为保存 participant 对象,即使该示例实际上是为了保存 getSchedule 接收到的计划对象。
我知道这里的区别在于被调用的方法是否应该返回某些东西(在这种情况下,它会返回被调用的对象本身以进行链接)。但这两种情况与符号本身没有区别,只能从被调用方法的语义上区分。当不使用方法链接时,我总是可以知道方法调用对与前一个调用的 result 相关的东西进行操作 - 使用链接,这个假设就被打破了,我必须在语义上处理整个链了解被调用的实际对象到底是什么。例如:
participant.attend(event).setNotifications('silent').getSocialStream('twitter').postStatus('Joining '+event.name).follow(event.getSocialId('twitter'))
最后两个方法调用引用 getSocialStream 的结果,而前面的调用引用参与者。也许在上下文发生变化的地方实际编写链是不好的做法(是吗?),但即使那样,您也必须不断检查看起来相似的点链是否实际上保持在相同的上下文中,或者只处理结果.
在我看来,虽然方法链接在表面上确实产生了可读的代码,但重载点符号的含义只会导致更多的混乱。因为我不认为自己是编程大师,所以我认为是我的错。 那么:我错过了什么?我是否理解方法链接有些错误?在某些情况下方法链接特别好,或者有些情况特别差?
旁注:我理解这个问题可以被解读为一个被伪装成问题的观点陈述。然而,事实并非如此——我真的很想了解为什么链接被认为是好的做法,以及认为它破坏了固有的面向对象表示法我哪里错了。
【问题讨论】:
-
似乎方法链至少是用java编写智能代码的一种方式。即使不是每个人都同意..
-
他们也称这些“流利的”方法或“流利的”接口。您可能需要更新您的标题以使用该术语。
-
在另一个 SO 讨论中,据说流式接口是一个更大的概念,与代码可读性有关,而方法链接只是实现这一目标的一种方式。不过它们是密切相关的,所以我确实在文本中添加了标签和引用的流畅接口——我认为这些就足够了。
-
我想到这一点的方式是,方法链接实际上是一种将缺少的功能添加到语言语法中的变通方法。 真的很糟糕如果有一个内置的替代符号
.将忽略任何方法返回值并始终使用同一对象调用任何链式方法,则不需要 '。 -
这是一个很棒的编码习惯,但就像所有很棒的工具一样,它也被滥用了。
标签: oop fluent-interface method-chaining