Является ли изменение параметров объекта в методе (в Java) плохой практикой? - PullRequest
0 голосов
/ 28 августа 2018

У меня есть вопрос о мутировании параметров-параметров (которые являются объектами) в методе.

Я много раз читал и слышал, что это плохая практика - мутировать объект в методе, который был передан как параметр. Как пример:

public void modifyList(List<Object> list) {
    list.add(new Object());
}

Вместо этого переданный объект должен быть скопирован, мутация должна быть выполнена на скопированном объекте, и скопированный объект должен быть возвращен. Как пример:

public List<Object> getModifiedList(List<Object> list) {
    List copy = new List<Object();
    //Make a deep copy if it would be necessary
    for(Object o : list) {
        copy.add(o.clone());
    }
    //Modify the copy
    copy.add(new Object());
    //return the copy
    return copy;
}

Я понимаю, что второй метод имеет меньший потенциал для побочных эффектов, потому что он не изменяет входной параметр.

Но так ли это на самом деле? Производительность пострадает, потому что нужно создать много глубоких копий. Кроме того, реализация копирующих конструкторов и реализация методов-клонов для всех классов будет стоить много времени. Также это увеличило бы LOC.

На практике я не часто вижу этот шаблон (скопируйте метод-параметр).

Может ли кто-нибудь с большим опытом (много лет работающий программистом / разработчиком программного обеспечения) ответить на этот вопрос?

Поздравления Maverin

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Это зависит от вашего варианта использования, как вы уже подразумевали. Обеспечение неизменности ваших компонентов дает множество преимуществ, таких как улучшенная инкапсуляция , безопасность потоков , , позволяющая избежать недопустимого состояния и т. Д. Конечно, таким образом вы реализуете производительность удар. Но кто-то с большим опытом написал об этом главу, которую я могу только рекомендовать:

Эффективная Java -

Item 50: Делайте защитные копии, когда это необходимо.

Там он рекомендует:

Вы должны программировать в обороне, предполагая, что клиенты вашего класса сделают все возможное, чтобы уничтожить его инварианты.

, а также:

Таким образом, если у класса есть изменяемые компоненты, которые он получает или возвращает своим клиентам, класс должен защищенно копировать эти компоненты. Если стоимость копирования будет непомерно высокой, и класс будет доверять своим клиентам не изменять компоненты ненадлежащим образом, защитная копия может быть заменена документацией с указанием ответственности клиента за не модификацию затронутых компонентов.

0 голосов
/ 28 августа 2018

Оба метода хороши и могут быть правильным выбором в зависимости от вашего варианта использования. Просто убедитесь, что вы называете их так, чтобы прояснить намерения, и напишите какой-нибудь Javadoc.

Затем разработчик должен решить, будет ли изменен оригинальный список, или нет, а если нет, передать копию или использовать другой метод.

Например, этот метод из JDK изменяет существующий список, но его намерения и документация очень ясны.

...