【发布时间】:2012-03-12 19:43:24
【问题描述】:
毫无疑问,输入输出参数会导致代码混乱,因为它们可能会增加意外/不可预测的副作用。
所以,很多优秀的程序员说:
避免更改可变方法参数的输入输出参数。最好保持参数不变。
对于一个希望自己的代码最简洁易懂的完美主义程序员来说,这个“规则”是否必须适用于所有情况?
例如,假设一个简单的列表添加元素的基本方法,有两种方法:
第一种方式(带入出参数):
private void addElementsToExistingList(List<String> myList){
myList.add("Foo");
myList.add("Bar");
}
调用者是:
List<String> myList = new ArrayList<String>();
//.......Several Instructions (or not) .....
addElementsToExistingList(myList);
不带out参数的第二种方式:
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;
}
调用者是:
List<String> myList = new ArrayList<String>();
//.......Several Instructions (or not) .....
myList.addAll(addElementsToExistingList(myList));
第二种方式的优点:
参数不被修改 => 对于新的代码阅读器没有意外副作用的风险。
第二种方式的缺点:
非常冗长且可读性极差......
当然,你会告诉我,对于这么简单的代码,第一种方法确实更方便。
但是,如果我们不考虑任何概念/代码的难度,我认为第二种方式对任何读者(无论是否初学者)来说都更合乎逻辑和更明显。
但是,它违反了 CQS 原则,即认为“命令”方法具有潜在的 void 返回(但由于它是惯例是允许的)副作用和具有返回类型且没有副作用的“查询”方法。
那么,激励程序员应该采用什么?根据代码情况混合两个?或者保持“规律”期望总是避免输入输出参数......
(当然,添加元素的方法是为显式示例而命名的,在实际代码中将是一个不好的名称选择。
【问题讨论】:
标签: java refactoring parameter-passing