Как правильно возвращать значение из геттера?
Проходя тему геттеров и сеттеров оставался один вопрос: Необходимо ли каждый раз возвращать клонированный объект из геттра? Я знаю что примитивные типы данных автоматически клонируются, но что делать с объектами, особенно если там большая вложенность?
Например, есть какой-то объект, мы его возвращаем без клонирования (то есть возвращаем ссылку), далее в коде изменяем его и выводим на экран, при этом изменяется и сам объект в классе, что недопустимо.
Какие варианты вижу я:
- С помощью SerializationUtils.clone() делать глубокое клонирование и возвращать объект, далее, если его нужно будет изменить в самом классе, делаю это с помощью сеттера. Вижу только одну проблему, если будет что-то тяжёлое, то глубокое клонирование сильно замедлит программу.
- Отдать ссылку и если это необходимо клонировать объект уже в коде.
Когда отдавать ссылку, а когда глубокую копию объекта?
public class Game { Player player = new Player(); Field gameField = player.getField(); // Изменили объект в самом классе, так как отдали ссылку Field newField = SomeClass.change(gameField); System.out.println(newField); } |
public class Game { Player player = new Player(); Field gameField = player.getField(); // Изменили объект в самом классе, так как отдали ссылку Field newField = SomeClass.change(gameField); System.out.println(newField); }
public class Player { private Field field; public Field getField() { return this.field; } } |
public class Player { private Field field; public Field getField() { return this.field; } }
Дополнительно:
Полностью зависит от контекста. Здесь нет правильного ответа.
Можно выделить 2 случая:
1. Код полностью твой
2. Код будут использовать другие пользователи
Если случай 1, то делай как хочешь. Здесь ты главный и знаешь что менять можно, а что нет
Если случай 2, то тут уже зависит:
- Если возвращаешь объект, который может (и должен) быть изменен - делай изменяемым
- Если это слепок состояния - то можно подумать над неизменяемым состоянием
- Можно прописать это (то что нельзя изменять объект) в документации к методу геттера
Дополнительно, если тебе так уж нужна неизменяемость, то добавляй интерфейсы. Возвращай какой-нибудь интерфейс с одними геттерами.
геттер всегда возвращает ссылку на один и тот же объект, это просто способ доступа к членам класса
(иначе если в коде два вызова геттера - будет создано два новых объекта?),
если геттер создает новый объект - это не геттер и его лучше оформить отдельным методом
в яве даже Cloneable интерфейс ввели чтобы подчеркнуть особый случай
PS: стоит посмотреть на паттерны Prototype и Factory
Ответы:
Желательно возвращать либо иммутабельные объекты (LocalDateTime вместо java.util.Date)
либо клонировать.
Если вернуть сложный объект со связями, то дальнейшее использование этого может
привести к сложным и трудно-воспроизводимым багам.
Разумеется жизнь полна исключений и тут главное чтоб вся команда разработчиков ПОНИМАЛА что
ты сделал и для чего. Иначе будут конфликты и война правок в коде проекта.
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Чтобы правильно возвращать значение из геттера, необходимо следовать определенным правилам и рекомендациям:
1. Название метода: название геттера должно начинаться с префикса "get", за которым следует имя переменной с большой буквы. Например, для переменной $name геттер должен называться getName().
2. Возвращаемое значение: геттер должен возвращать значение переменной без изменений. Не следует в геттере производить какие-либо вычисления или преобразования данных.
3. Использование внутри класса: для доступа к переменным класса рекомендуется использовать геттеры вместо обращения к переменным напрямую. Это позволяет легко изменить логику доступа к переменным в будущем.
Пример реализации геттера на языке PHP:
class User { private $name; public function getName() { return $this->name; } public function setName($name) { $this->name = $name; } } $user = new User(); $user->setName('Alice'); echo $user->getName(); // выведет 'Alice'
Следуя этим правилам, вы сможете корректно и эффективно использовать геттеры для получения значений переменных в вашем коде.