Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Приватные свойства - зачем? #137

Open
Gerych1984 opened this issue Sep 20, 2021 · 4 comments
Open

Приватные свойства - зачем? #137

Gerych1984 opened this issue Sep 20, 2021 · 4 comments

Comments

@Gerych1984
Copy link

Доброго дня. Т.к. свой новый корпоративный проект я решил сразу начать на yii3, то возник ряд вопросов/непониманий. Относятся они наверно ко всему yii3, но живой кейс возник с виджетом табов, поэтому напишу сюда.

Итак имеем:

  1. Виджет табов, у которого все свойства приватны и имееют type hint
  2. Сеттер на каждое свойство (зачем там устанавливается через clone мне тоже непонятно, но опустим)
  3. В конструкторе виджета генерируется $options['id'] если не установлен

Мой "живой" случай в идеале, но не как сейчас:

$tabs = Tabs::widget();
//Ставим остальные свойства через сеттер

$this->registerJs('Vue.createApp(SourceTabsOptions).mount("#' . $tabs->options['id'] . '");');

Т.е. мне всё-равно какой id сгенерится виджетом, у меня к нему не привязано никаких CSS, ни чего другого. Но сейчас я вынужден каждый раз выдумывать этот самый id элемента, т.к. не могу получить приватный $options

Вопрос - а почему эти свойства не сделать публичными?

  1. Из-за type hint'ов я не смогу поставить недопустимое значение
  2. Это избавит от написания кучи однообразных сеттеров, которые по сути делают тоже самое
  3. При наличие того-же сеттера, приватные свойства не имеют смысла - т.к. я в любой момент могу его изменить через него.

При этом, если допустить ошибку и забыть при конфигурации указать "()" в конце, то yii3 заботливо предлагает добавить "$" в начало, чтобы установить свойство - что опять-же не работает с приватными свойствами. Но как минимум я так полагаю, что задумка такая была, но сейчас я мало где вижу ей применение, т.к. практически всё либо private, либо в лучшем случае protected

Заранее благодарен

@vjik
Copy link
Member

vjik commented Sep 20, 2021

For get id we can make method getId() public.

Private properties and getter/setters allow easier to make changes in the future, create readonly or writeonly properties, also in most cases getter or setter perform additional actions (for example, in Tabs setters make clone of widget).

Clone are needed in order for the widgets to be immutable.

@Gerych1984
Copy link
Author

For get id we can make method getId() public.

Private properties and getter/setters allow easier to make changes in the future, create readonly or writeonly properties, also in most cases getter or setter perform additional actions (for example, in Tabs setters make clone of widget).

Clone are needed in order for the widgets to be immutable.

Делать getId() пабликом бессмысленно - т.к. на каждый вызов он будет генерить новый id за счёт накручивающегося счётчика + у данных виджетов "по хардкору" вписан суффикс (-tabs, -alert и т.д.) который может быть изменён в следующих релизах или вообще исчезнуть.

И перефразирую - readonly свойства нужны, не спорю. НО сейчас получается нет никаких read свойств, никаких геттеров - по сути мы имеем сплошное writeonly, т.е. мы можем установить значение, но не можем обратно получить. А это зачастую нужно и именно после манипуляций с этим свойством самим виджетом.

Ну и ИМХО - иммутабельность иммутабельностью, но может не стоит возводить её в абсолют, особенно там где она не "делает погоды"? Т.е. вот тут я не вижу от этого пользы, т.к. всё что требуется - это отрисовать нужный мне контент, в нужном мне месте в зависимости от виджета, всё. Но вижу вред - вынужден ждать когда будут потрачены человекочасы на написание геттеров к каждому свойству у которого есть сеттер и не факт, что они вообще будут написаны (хотя хватило бы просто сделать часть свойств, которые может установить пользователь публичными)

Т.е. к примеру я в миграциях повсеместно напрямую использую ColumnSchemaBuilder, чтобы дополнить недостающие в MigrationBuilder нативные pgsql типы (point, *range, uuid) и никаких проблем с отсутствием в нём иммутабельности я не обнаружил

@vjik
Copy link
Member

vjik commented Sep 21, 2021

In getId() id generated once (see code) and saved in private property.


If getters real need (has use cases), then we should added their.


In modern IDEs create base setters/getter very simple. For example, in PhpStorm:
image


Immutable objects making impossible to make certain types of mistakes. When we pass an object to somewhere, we are sure that it will not change.

@samdark samdark transferred this issue from yiisoft/yii-bootstrap5 Sep 25, 2021
@WinterSilence
Copy link

Виджет табов, у которого все свойства приватны и имееют type hint

что удивительного в доступе к свойствам через сеттер/геттер?

Сеттер на каждое свойство (зачем там устанавливается через clone мне тоже непонятно, но опустим)

почитай о immutable objects

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

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

Для понимания подобных концепций стоит вначале ознакомится с SOLID

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants