如马丁的《清洁法》所指,输出自变量是什么?


14

在Robert C. Martin的“清洁代码:敏捷软件技巧手册”的第45页上,Martin写道,应避免使用输出参数。我在理解“输出参数”的含义以及为什么应避免使用它们时遇到了麻烦。

马丁的输出参数示例appendFooter(s);调用了function public void appendFooter(StringBuffer report)。他对代码的改进是report.appendFooter();

也许是由于缺少代码上下文所致,但是我看不出如何使用输出参数被认为是较差的编码。有人可以解释这个概念或提供其他示例代码来理解这一点吗?

根据上述原理,以下功能是否也可以视为不洁代码的示例?

int[] numberArray = {3, 5, 7, 1};
sortArray(numberArray);

如果以上内容违反了马丁不使用输出参数的原则,那么最好让一个对象具有一个数组作为字段和一个可以调用以对数组进行排序的函数?

ObjectWithArrayField numberArray = new ObjectWithArrayField(3, 5, 7, 1);
numberArray.sort();

Answers:


11

鲍勃·马丁(Bob Martin)只是在谈论可读性

appendFooter示例的问题是,如果您在程序中的appendFooter(s)某个位置找到了代码行 ,则该调用是否s作为输入并将其追加到某个位置,或者是否s只是通过传递以获取该函数的输出,并不是立即显而易见的。可以肯定的是,您需要查看功能文档。report.appendFooter()但是,像这样的调用避免了这个问题:现在发生的事情更加明显。

但是请注意,鲍勃·马丁(Bob Martin)并没有说“从不使用输出参数”,而是说“通常应该避免使用它,因为这将帮助您使代码更加整洁”。因此,这不是盲目追求货色的规则,应该盲目遵循。

Sort标准数组和集合的方法略有不同。sort从语言设计者的角度来看,使该方法成为每个标准数组数据类型的成员函数将具有一些缺点,例如,具有一种Array.sort允许将其保留在Java运行时之外的标准库中的方法。但是,如果您要创建一个有时需要排序的单个集合类型,那么将其添加sort为成员函数确实比将其放入单独的类中更好。


2
sortArray(numberArray),当然排序numberArray到位。还是制作一个的副本numberArray,对该副本进行排序,然后返回排序后的副本而不进行任何更改numberArray
8bittree

@ 8bittree:是的,但这不是讨论的重点- sort()容器的方法也可以就地工作,而无需使用“输出参数”。因此,仅因为sortArray(numberArray)就地方法绝对是没有理由证明“输出参数形式”合理。
布朗

1
我的意思是,sortArray(numberArray)所做的并不完全清楚。很明显,如果它没有返回与接受的类型相同的类型,那么它必须就位。但是没有看到返回类型,或者如果返回类型与输入类型匹配,则不看定义就不清楚。
6

1
@ 8bittree:好的,您明白了,我从答案中删除了要害声明。但是,您所描述的问题不会通过使用成员函数而消失-甚至“排序”成员函数也可以采用这种方式。
布朗

11

这是使用意外的机制从函数返回值的问题,这通常是由于在函数中执行了太多操作或职责错位造成的。到目前为止,传达函数结果的最佳方法是使用返回值。我希望这是不言而喻的。在面向对象的语言中,第二好的方法是对对象进行突变。

在这两个选项之间,有太多清晰,明显的方式来传达函数的结果,以至于如果您发现自己想要改变参数作为唯一手段,那么您的体系结构就会出现问题。您需要重新安排班级职责,以便首先进行更改的人员拥有数据。

一个例外是非常通用的算法。例如,如果排序算法可以使用其公共接口通用地应用于任何类型的容器,则排序算法可能正好与其排序的容器分开。一键式appendFooter功能没有这个借口。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.