Хорошая практика для редактирования объектов "по ссылке"? - PullRequest
11 голосов
/ 15 июля 2010

Допустим, у меня есть тип с именем Superstar. Теперь я хочу иметь метод, который выполняет некоторую работу и редактирует некоторые свойства объекта Superstar.

Вот два способа, как я мог бы это реализовать. Путь 1 будет следующим:

private Superstar editSuperstar(Superstar superstar){
    ....
    superstar.setEdited(true);
    return superstar;
}
...
superstar = editSuperstar(superstar);

И путь 2 будет таким:

private void editSuperstar(Superstar superstar){
    ....
    superstar.setEdited(true);
}
...
editSuperstar(superstar);

Какой из этих двух возможных способов считается «наилучшей практикой»? Первый или второй псевдо "по ссылке" один?

Ответы [ 5 ]

6 голосов
/ 15 июля 2010

В вашем случае вторая форма предпочтительнее, так как вы напрямую изменяете одно из свойств суперзвезды (edited).Однако, если у вас есть метод, который использует объект суперзвезды и возвращает его обновленную версию (без изменения начальной), первая форма будет иметь мою пользу.

Наконец, поскольку в обоих примерах используется только суперзвездаобъект, они должны быть методами-членами класса Superstar.

4 голосов
/ 15 июля 2010

Первая форма обманчива. Создается впечатление, что передается один объект, который копируется, а затем копия изменяется и возвращается.

«Лучшая практика» - использовать первую форму, но фактически делать то, что подразумевается (применить изменение к копии, которая затем возвращается). Неизменяемые объекты обычно предпочтительнее изменяемых объектов, если только они не являются крупными, объемными вещами, которые дорого копировать, в этом случае вам следует отдать предпочтение второй форме.

4 голосов
/ 15 июля 2010

Используйте способ 2, если только вы не создаете класс "builder", в котором вы собираетесь связывать вызовы.Пример:

MyClass c = (new MyClassBuilder()).setX(blah).setY(blah).build();
2 голосов
/ 15 июля 2010

Проблема, с которой вы столкнулись при использовании первого метода, заключается в следующем:

Superstar edited = editSuperstar(originalSuperstar);

Это также изменит оригинал Superper, который, на мой взгляд, нелогичен ...

Таким образом, предпочитайте второй, если вы изменяете переданный объект, или первый, если вы возвращаете новую копию объекта.

Для этого специфического примера вы можете просто добавить метод редактирования в класс Superstar ...

1 голос
/ 15 июля 2010

Первая форма будет удивительной для клиентов API, если вы вернете тот же экземпляр, изменив только некоторые поля. Можно ожидать возврата измененной копии без изменения исходного экземпляра.

Так что используйте вторую форму, если вы не возвращаете копию, и используйте первую, если вы это делаете (и подумайте о том, чтобы сделать Superstar неизменной в этом случае).

...