总是避免Java中的in-out参数?

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的方法被命名用于表示示例,并且在实际代码中将是一个错误的名称选择).

thk*_*ala 5

我认为法律应该是:

用的是更直接的,但总是,总是大量文献证明你的方法的行为.

您的第二个示例是一个非常好的情况,如果没有文档,您将有一个保证的错误:方法的名称是addElementsToExistingList,但该方法不会向现有列表添加元素 - 它会创建一个新的元素.一个反直觉和误导性的名字,至少可以说......