Незмінність є однією з найважливіших концепцій проектування для побудови стабільних додатків. Основний принцип полягає в тому, що після того, як держава записана, вона може бути лише прочитана пізніше без можливості її модифікації. Якщо нам потрібно змінити стан, ми повинні створити новий екземпляр і замінити весь об'єкт на інший.
Таким чином, типи даних можна дуже грубо розділити на дві великі категорії:
Об'єкти, що змінюються, можуть бути змінені внутрішньо. Тобто, вони забезпечують операції, які при виклику в різних комбінаціях призводять до того, що ми отримуємо різні результати. Незмінність намагається запобігти такій поведінці.
Клас є незмінним саме тоді, коли дані екземпляру не можуть бути змінені жодним чином після створення екземпляру.
Тобто всі дані фіксуються в конструкторі. Всі скалярні типи даних також є автоматично незмінними.
Проектування додатків з незмінними станами дає принципову перевагу в безпеці виконання операцій. Якщо ми знаємо, що одного разу записані дані не можуть бути змінені (мутовані) пізніше, ми можемо, наприклад, дуже надійно налагоджувати, або розбивати додаток на підфункції без ризику забути будь-який з проміжних станів.
Ідея незмінності, як правило, протистоїть принципу зберігання станів у властивостях об'єктів/сутностей, а скоріше описує функціональний підхід, коли дані просто "протікають" через додаток, як це робить, наприклад, javascript.
З точки зору продуктивності, ми можемо автоматично сказати про незмінні об'єкти, що їх можна кешувати нескінченно довго, тому що вони ніколи не будуть застарілими.
На сьогоднішній день найпоширенішим використанням незмінних об'єктів в PHP є об'єкт DateTimeImmutable
, який після створення може бути викликаний тільки методами форматування. Якщо ми змінимо внутрішні налаштування, метод поверне новий екземпляр. Ця функція має вирішальне значення при використанні ORM, який використовує так званий шаблон ідентичності - вона дозволяє нам, наприклад, гарантувати, що коли ми зчитуємо дату створення замовлення, вона буде однаковою скрізь у додатку і посилальна цілісність не буде порушена.
Конкретний приклад мутабельного об'єкту:
$date = new DateTime('2021-05-14');$tomorrow = $date->modify('+1 день');echo $date->format('Д-д-д'); // 2021-05-15echo $tomorrow->format('Д-д-д'); // 2021-05-15
Була виведена та сама дата, тому що метод modify()
лише змінив внутрішній стан об'єкту DateTime
і повернув той самий екземпляр. Таким чином, не було так званої мутації внутрішнього стану, яка є базовою поведінкою об'єктно-орієнтованого програмування. Оновлення змінної також змінило вихідну змінну.
А тепер приклад незмінного об'єкта:
$date = new DateTimeImmutable('2021-05-14');$tomorrow = $date->modify('+1 день');echo $date->format('Д-д-д'); // 2021-05-14echo $tomorrow->format('Д-д-д'); // 2021-05-15
Об'єкт DateTimeImmutable
є незмінним, що означає, що його внутрішній стан ніколи не змінюється. Новий модифікований екземпляр (також незмінний) зберігається у змінній після виклику методу modify()
. Якби ми не зберегли нове значення у змінній, вона не була б придатною для подальшого використання.
Оригінальна вартість ніколи не чіпається і залишається надійно збереженою.
Якщо у вас немає дуже вагомої причини зробити його змінюваним, завжди пишіть клас або функцію як незмінний. Це спростить ваше проектування в майбутньому.
Змінювані класи повинні змінюватися якомога менше. Я завжди рекомендую документувати поведінку незмінності.
Мабуть, єдиним недоліком незмінності є те, що при кожній зміні атрибутів необхідно створювати новий екземпляр, що має незначний вплив на продуктивність. Якщо ваша програма (як і більшість програм) має тенденцію до відображення даних і рідше їх змінює, цей недолік є досить незначним з урахуванням продуктивності сучасних комп'ютерів.
Що не повинно бути непорушним:
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | uk