Getter’и та Setter’и

PHP. Особливості та фічі

Прямий ефір

hui_nana 28 травня 2014, 13:33

Grover 26 травня 2014, 11:42

Grover 26 травня 2014, 11:41

hui_nana 23 травня 2014, 10:26

  • Frontend7.96
  • Yii framework7.92
  • Q&A6.03
  • OS Linux5.66
  • CMS 1C-Bitrix5.65
  • PHP. Продукти4.63
  • PHP. Продуктивність4.53
  • PHP. Особливості та фічі4.53
  • Безпека4.52
  • HTML51.25

Джозеф Кроуфорд, один із моїх читачів, прочитав статтю про те, як я не люблю писати getter'и та setter'и і припустив, що я можу використовувати чарівні методи __get та __set. Я скажу вам, чому це не дуже хороша ідея використовувати їх звичайним способом. Крім того, я збираюся розповісти вам історію, де вони справді виявилися корисними, — йтиметься про створення статичних типів у PHP (динамічна мова). Для тих, хто не знайомий з методами __get і __set — це два «магічні» методи, які працюють таким чином:

Як правило, перераховані вище методи використовуються для створення динамічних властивостей. Який висновок можна із цього зробити? Якщо ви хочете створювати будь-які випадкові властивості, просто використовуйте хеш (він же масив із ключами). Що ж хорошого в getter'ах та setter'ах? Давайте подивимося:

Що? Вага із негативним значенням? Це з більшості поглядів неправильно. Корова не повинна важити менше 100 кг (я так думаю:). У межах 1000 – допустимо. Як нам забезпечити таке обмеження. Використовувати __get та __set — досить швидкий спосіб.

А що якщо у вас є клас із 10—20 властивостями та перевірками для них? Уцьому разі неприємності неминучі.

І навпаки, getter'и та setter'и виявляють себе з кращого боку, коли справа доходить до перевірки даних.

Ніщо не порівнюється з короткими функціями з C#. Можливо, така підтримка скоро з'явиться в PHP, ну а поки не розслабляємося ... Кожен спосіб несе відповідальність тільки за свою область, завдяки цьому в коді легше орієнтуватися. Все одно виходить занадто багато коду, але він чистіший, ніж __set-версія. Існує хороший евристичний підхід, який полягає в наступному: якщо ваш метод (функція) займає більше ніж 1 екран – потрібно скорочувати. Це покращить сприйняття коду. Ми також зберігаємо деяку бізнес-логіку. Копит завжди буде рівно стільки, скільки і ніг, а якщо ми помітимо зміну ваги худоби, ми відразу повідомимо пастуха. Оскільки ми не дбаємо про прізвиська корів і не перевіряємо їх, нехай дані будуть загальнодоступними без getter'ів і setter'ів. Знову ж таки, я дійсно не писав всіх цих getter'ів і setter'ів — PHP Storm зробив це за мене. Я просто написав таке:

і натиснув Alt+Insert -> Getters та setters. PHPStorm згенерував все автоматично. Тепер у вигляді додаткової переваги PHP Storm при роботі з getter'ами та setter'ами маю можливість використовувати функцію автозаповнення:

У випадку __get я не маю такої можливості, я можу лише написати це:

Тепер корова "важить" (wIEghts) мінус 100 кг. Я можу забути, що це вага в кг, досить просто написати weight - все працюватиме. Отже, getter'и and setter'и бувають дуже навіть корисні (але все ж таки не поклоняйтеся їм, ви ж не програміст Java). Якщо вам просто потрібні вільні властивості, використовуйте масив:

Цей трюк набагато легшепровернути, ніж __get та __set. Але, якщо ви хочете бути впевненим, що ваші дані завжди мають лише допустимі значення, використовуйте setter'и з перевіркою. За наявності інтегрованого середовища розробки (IDE), типу PHP Storm, ви любитимете setter'и, тому що вони дуже прості у використанні. Замість $cow->setLegs() для PHP Storm достатньо буде набрати co[TAB]sl[TAB]. Та легко! Немає більше друкарських помилок, і ви можете бачити, які параметри приймає метод. Метод __set має ще один недолік. Він приймає лише один параметр. Що робити, якщо вам потрібно 2? Наприклад, як тут: $store1->setPrice('item-1', 100). Вам необхідно встановити ціну товару у магазині. Метод __set не дозволить вам цього зробити, а setter дозволить.