方法链接 是对象方法返回对象本身以便为另一个方法调用结果的实践。像这样:
participant.addSchedule(events[1]).addSchedule(events[2]).setStatus('attending').save()
这似乎被认为是一个很好的实践,因为它产生了可读的代码,或者说是一个“流畅的接口”。然而,对我来说,它似乎打破了面向对象本身所隐含的对象调用表示法——产生的代码并不代表对之前方法的 结果执行操作,而面向对象的代码通常就是这样工作的:
participant.getSchedule('monday').saveTo('monnday.file')
这种差异为点符号“调用结果对象”创建了两种不同的含义: 在链接的上下文中,上面的示例将被理解为保存 参与者对象,即使这个示例实际上是为了保存 getScheme 接收到的调度对象。
我理解这里的区别在于是否应该期望被调用的方法返回某些内容(在这种情况下,它将返回被调用的对象本身以进行链接)。但是这两种情况并不能与符号本身区分开来,只能从被调用方法的语义上区分开来。当没有使用方法链接时,我总能知道一个方法调用操作的是与前一个调用的 结果相关的东西——通过链接,这个假设被打破了,我必须从语义上处理整个链接来理解实际被调用的对象到底是什么。例如:
participant.attend(event).setNotifications('silent').getSocialStream('twitter').postStatus('Joining '+event.name).follow(event.getSocialId('twitter'))
最后两个方法调用引用 getSocialStream 的结果,而之前的方法调用引用参与者。也许在上下文发生变化的地方实际编写链是不好的做法(是吗?),但即使这样,你也必须不断地检查看起来相似的点链是否实际上保持在相同的上下文中,或者只对结果起作用。
在我看来,虽然方法链表面上确实产生了可读的代码,但是重载点符号的含义只会导致更多的混淆。因为我不认为自己是一个编程大师,所以我认为是我的错。我错过了什么?我是不是理解错了方法链接?是否存在方法链特别好的情况,或者存在特别糟糕的情况?
旁注: 我理解这个问题可以被理解为一个隐藏在问题背后的意见陈述。然而,它不是——我真的想知道为什么链接被认为是一种好的实践,我在哪里错误地认为它打破了固有的面向对象符号。