Страницы

Поиск по вопросам

суббота, 30 марта 2019 г.

Чем канонические геттеры и сеттеры лучше открытого поля?

Не понимаю, в чем плюс использования канонических (только возвращающих и устанавливающих занчение) геттеров и сеттеров перед открытым полем? Чем вот такой код:
private MyJDesktopPane desktop;
public MyJDesktopPane getDesktop() { return desktop; }
public void setDesktop(MyJDesktopPane desktop) { this.desktop = desktop; }
Лучше такого:
public MyJDesktopPane desktop;
Понимаю, если в сеттере например используются какие-либо проверки на корректность введенного значения или идет согласование введенного значения с другими полями класса.
Скажу честно, до проблемы додумался не сам, прочитал о ней в статье "10 приемов, разрушающих хрупкую красоту кода" на Хабре.


Ответ

Это "запас на будущее".
Сейчас вам достаточно поля, так как у вас публичны и чтение, и запись, а никакой дополнительной логики нет. Теперь допустим, что вам понадобилась эта логика. Что вы будете делать? Вы скроете поле, напишете геттеры и сеттеры. И тут возникает проблема: надо переписать все доступы к полю во всех классах, работающих с вашим кодом; надо перекомпилировать весь код, который обращается к полю. Часто это может быть большой объём работы, и он может повлечь за собой тьму тьмущую неприятностей, особенно если одновременно поддерживается несколько версий приложения: привет конфликтам мержа кода и прочим радостям.
Всё потому, что изменение поля на геттеры и сеттеры — это изменение, ломающее обратную совместимость, а добавление логики в геттер или сеттер — совершенно безболезненное изменение реализации. При хорошей архитектуре изменение реализации не должно влиять на внешний интерфейс и не должно ломать обратную совместимость. Поэтому предпочтение отдаётся геттерам и сеттерам даже тогда, когда реальной нужды в них нет.
Лирическое отступление: в C# синтаксис доступа к публичным полям и к публичным свойствам (парам геттер+сеттер) идентичен. Однако даже в C# считается дурным тоном использование публичных полей. Во-первых, потому что ломается бинарная совместимость, несмотря на сохранение совместимости на уровне сорцов; во-вторых, потому что публичные поля могут быть переданы по ссылке (ref, out), что невозможно для свойств.

Прочитал статью. Надо заметить, что рекомендация воздерживаться от геттеров и сеттеров в статье универсальна и оторвана от конкретных языков. Нельзя реализовать все рекомендации из статьи, если оставаться в рамках синтаксически аскетичного языка. Вы не можете воспользоваться синтаксическии сахаром в виде свойств, которые выразительнее, чем геттеры и сеттеры, если язык эти свойства не поддерживает. В этом случае придётся использовать геттеры и сеттеры, а не публичные поля, впрочем. Ну или переходите на C#. :)

Комментариев нет:

Отправить комментарий