На странице 45 «Чистого кода Роберта Мартина: Справочник по мастерству гибкого программного обеспечения» Мартин пишет, что выходных аргументов следует избегать. У меня возникают проблемы с пониманием значения «выходной аргумент» и почему их следует избегать.
Пример Мартина для выходного аргумента appendFooter(s);
вызывает функцию 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();
источник
sortArray(numberArray)
, конечно, сортируетnumberArray
на месте. Или он создает копиюnumberArray
, сортирует копию и возвращает отсортированную копию без каких-либо измененийnumberArray
?sort()
метод контейнера также может работать на месте, без использования «выходного аргумента». Так что только потому, чтоsortArray(numberArray)
метод на месте является абсолютно никакой причиной, которая оправдывает «форму выходного аргумента».sortArray(numberArray)
делает. Это может быть очевидно, если он не возвращает тот же тип, который принимает, то он должен быть на месте. Но не видя тип возвращаемого значения или если тип возвращаемого значения совпадает с типом ввода, неясно, не глядя на определение.Это вопрос использования неожиданного механизма для возврата значения из функции, который обычно является результатом слишком большого выполнения функции или несогласованных обязанностей. Безусловно, лучший способ сообщить результат функции - использовать возвращаемое значение. Я надеюсь, что это само собой разумеющееся. В объектно-ориентированных языках вторым лучшим методом является изменение объекта.
Между этими двумя вариантами есть так много чистых, очевидных способов сообщить результат функции, что, если вы когда-нибудь захотите изменить аргументы как единственное средство, что-то пошло не так в вашей архитектуре. Вы должны перестроить свои классовые обязанности так, чтобы тот, кто занимается мутацией, владел данными в первую очередь.
Единственное исключение для очень общих алгоритмов. Например, алгоритм сортировки может по праву отделяться от сортируемых контейнеров, если он может быть применен в общем случае к любому типу контейнера с использованием его открытого интерфейса. Функция «один выстрел»
appendFooter
не имеет такого оправдания.источник