Mik*_*378 4 java refactoring parameter-passing
毫无疑问,输入输出参数会导致代码混乱,因为它们可能会增加意外/不可预测的副作用.
所以,许多优秀的程序员说:
避免使用in-out参数来更改可变方法参数.希望保持参数不变.
对于一个完美主义程序员来说,他希望他的代码是最干净和最容易理解的,那么这个"规则"是否必须适用于所有情况?
例如,假设一种将元素添加到简单列表的基本方法,有两种方法:
第一种方式(带有输入参数):
private void addElementsToExistingList(List<String> myList){
myList.add("Foo");
myList.add("Bar");
}
Run Code Online (Sandbox Code Playgroud)
并且来电者是:
List<String> myList = new ArrayList<String>();
//.......Several Instructions (or not) .....
addElementsToExistingList(myList);
Run Code Online (Sandbox Code Playgroud)
没有参数的第二种方式:
private List<String> addElementsToExistingList(List<String> originalList){
List<String> filledList = new ArrayList<String>(originalList); //add existing elements
filledList.add("Foo");
filledList.add("Bar");
return filledList;
}
Run Code Online (Sandbox Code Playgroud)
并且来电者是:
List<String> myList = new ArrayList<String>();
//.......Several Instructions (or not) .....
myList.addAll(addElementsToExistingList(myList));
Run Code Online (Sandbox Code Playgroud)
第二种方式的优点:
参数未被修改=>没有新代码阅读器出现意外副作用的风险.
第二种方式:
非常冗长,可读性很差......
当然,你会告诉我,对于像这个简单的代码,第一种方法真的更方便.
但是,如果我们不考虑任何概念/代码的难度,那么对于任何读者(无论是否为初学者),我都认为第二种方式更具逻辑性和显而易见性.
然而,它违反了CQS原则,该原则认为"命令"方法具有具有潜在的空白返回(但是因为它是惯例而允许)副作用和具有返回类型且没有副作用的"查询"方法.
那么,激励程序员采用什么呢?两个混合代码案例?或者保持"法律"期望始终避免进出参数......
(当然,添加Element的方法被命名用于表示示例,并且在实际代码中将是一个错误的名称选择).
我认为法律应该是:
用的是更直接的,但总是,总是大量文献证明你的方法的行为.
您的第二个示例是一个非常好的情况,如果没有文档,您将有一个保证的错误:方法的名称是addElementsToExistingList,但该方法不会向现有列表添加元素 - 它会创建一个新的元素.一个反直觉和误导性的名字,至少可以说......