为何Setter方法不返回自身对象?该设计有何弊端?
在多数编程语言里,Setter(用于设置实例变量的方法)默认返回空值/Null,但如果让它返回对象本身,就能实现更便捷的链式调用(Fluent Interface),具体对比和示例如下:
代码对比
原写法
def set_x(x): self._x = x
修改后写法
def set_x(x): self._x = x return self
链式调用示例
原写法
data = ( data .filter(...) .map(...) ) data.set_x("X") data.set_y("Y")
修改后写法
data = ( data .filter(...) .map(...) .set_x("X") .set_y("Y") )
但这种设计存在不少弊端,也是它没成为主流的原因:
违反命令-查询分离原则:软件工程里的命令-查询分离原则要求,修改对象状态的「命令」方法不应该返回值,而查询状态的「查询」方法不能修改状态。Setter本质是修改状态的命令,返回self会混淆命令和查询的边界,容易让开发者误将其当作查询方法使用,依赖返回值做逻辑判断,埋下bug隐患。
隐藏状态修改的副作用:链式调用时,setter的状态修改操作会被「隐藏」在调用链里,阅读代码的人可能会误以为整个调用链都是无副作用的查询操作,增加了理解和调试的成本——尤其是复杂调用链中,很难快速定位哪个环节修改了对象状态。
打破既有开发习惯:几乎所有主流编程语言的开发者都已经形成了「Setter无返回值」的认知和代码习惯。如果语言层面强制修改,会打破大量现有代码的兼容性,也会增加新开发者的学习成本,反而得不偿失。
至于为什么没有编程语言普遍调整这个设计:
一方面是历史遗留和兼容性考量:早期编程语言设计时就遵循了命令-查询分离的理念,Setter的无返回值设计成为行业惯例,后续语言为了保持生态兼容性和认知一致性,也延续了这个约定。
另一方面,已有替代方案:如果需要链式调用,开发者可以通过Builder模式、专门的Fluent API类来实现,很多语言(比如Python、Java)也允许开发者自行实现返回self的Setter,完全可以按需定制,不需要语言层面强制改变默认行为。
内容的提问来源于stack exchange,提问作者Xaree Lee

