Шаблон дизайну стратегії
Шаблон розробки стратегії дозволяє визначити сімейство алгоритмів, інкапсулювати кожен з них і зробити їх взаємозамінними.
Код клієнта ( основний клас ) зможе вибрати алгоритм ( обслуговування ) під час виконання.
У цій статті ми глибше розглянемо шаблон проектування стратегії PHP Laravel, включно з прикладами
Стратегія шаблону дизайну
Il Стратегія шаблону дизайну потрапляє в категорію модель поведінки і дозволяє вибрати алгоритми під час виконання. Це особливо корисно в ситуаціях, коли потрібно динамічно перемикатися між ними алгоритм до іншого або від однієї поведінки до іншої.
В контексті Laravel/PHP, шаблон стратегії дозволяє вам відокремити певні алгоритми від клієнта, дозволяючи вам легко перемикатися між ними. Такого підходу дотримується Принцип відкритий/закритий (один із принципи ALONED ), дозволяючи коду бути відкритим для розширення, але закритим для модифікації.
проблема
У багатьох додатках Laravel, є сценарії, коли потрібно реалізувати кілька алгоритмів або поведінки на основі умов виконання. Наприклад:
у вас є програма, де користувачі можуть зареєструватися та користуватися вашими послугами. Тепер, очевидно, ви хочете захистити свою програму від підроблених облікових записів. Один із способів зробити це – запобігти реєстрації:
- Підроблені електронні листи
- Тимчасові або одноразові електронні листи
- Недійсні електронні адреси ( електронні листи, які здаються дійсними, але насправді не існують ).
Для цього ми можемо створити валідатор, який перевіряє одноразові електронні листи, а також перевіряти, чи дійсний електронний лист через зовнішнього постачальника.
Ми можемо використовувати kickbox.com як наш сервіс, і все нормально.
Що, якби ми також захотіли запровадити іншу послугу zerobounce.net, тоді ми можемо приступити до його реалізації.
Пізніше, припустімо, ми також оцінимо іншу потребу в підтримці usercheck.com , і так далі.
Завдяки шаблону стратегії ми можемо впоратися з цими потребами, не використовуючи такі твердження, як if-else
or switch
.
Якби натомість ми використовували більш структуроване програмування, а отже, з інтенсивним використанням if-else і перемикачів, ми б отримали щільне прилягання коду, через що нам буде дуже важко додавати або змінювати алгоритми на пізнішому етапі. Код стає складнішим, його важче тестувати та порушує ключові принципи дизайну.
Рішення
Il Шаблон стратегії пропонує елегантне вирішення цієї проблеми шляхом поділу алгоритмів на окремі класи, які реалізують загальний інтерфейс. Основна ідея:
- Визначте інтерфейс, який буде реалізовано всіма алгоритмами.
- Реалізуйте кожен алгоритм у своєму конкретному класі.
- Контекстний клас використовує ці алгоритми та може динамічно перемикатися між ними без зміни внутрішньої логіки.
Це означає чистий і підтримуваний код , легко розширювати та змінювати без зміни існуючої логіки. За потреби просто додайте нові стратегії, не змінюючи код клієнта.
Перш ніж ми заглибимося в реалізацію, давайте розберемося з ключовими компонентами, які складають модель спостерігача.
- Контекст : об’єкт, який делегуватиме свою поведінку одній із наявних стратегій.
- Інтерфейс стратегії : інтерфейс, який визначає поведінку для всіх стратегій. Стратегії реалізують цей інтерфейс, щоб забезпечити унікальну реалізацію поведінки.
- Конкретні стратегії : класи, які реалізують інтерфейс стратегії. Кожна стратегія інкапсулює певну поведінку, на яку контекст може перемикатися під час виконання.
Кодекс
- Стратегічний інтерфейс . По-перше, ми створюємо спільний інтерфейс для різних стратегій перевірки.
<?php
інтерфейс EmailValidationServiceInterface
{
публічна функція isRealEmail(рядок $email): bool;
}
2. Тепер давайте створимо кілька конкретні стратегії для кожної служби, яку ми хочемо запровадити: Kickbox, Zerobounce та Usercheck.
<?php
Клас KickboxService реалізує EmailValidationServiceInterface
{
публічна функція isRealEmail(рядок $email): bool
{
// Особлива логіка KickboxService
повернути правду;
}
}
клас ZeroBounceService реалізує EmailValidationServiceInterface
{
публічна функція isRealEmail(рядок $email): bool
{
// Спеціальна логіка ZeroBounceService
повернути правду;
}
}
Клас UsercheckService реалізує EmailValidationServiceInterface
{
публічна функція isRealEmail(рядок $email): bool
{
// Особлива логіка UsercheckService
повернути правду;
}
}
3. Тепер нам потрібно реалізувати a клас контексту . Це відповідає за вибір відповідної стратегії служби перевірки.
<?php
клас EmailValidationContext
{
private EmailValidationServiceInterface $emailValidation;
публічна функція setEmailValidator(EmailValidationServiceInterface $emailValidation): EmailValidationServiceInterface
{
$this->emailValidation = $emailValidation;
}
публічна функція validate(рядок $email): bool
{
return $this->emailValidation->isRealEmail($email);
}
}
використання
Остання частина - це те, як ми можемо використовувати стратегію в нашій програмі. Ми можемо реалізувати стратегію перевірки електронної пошти безпосередньо в нашому контролері або в спеціальному валідаторі Laravel.
<?php
клас RegisterController розширює Controller
{
публічна перевірка функції (запит $запит)
{
$emailValidationContext = новий EmailValidationContext();
// Для аргументації припустимо, що послуга надходить із запиту
// або ще краще налаштовується в `/config/services.php`
// Виберіть стратегію на основі вибраного сервісу
перемикач ($request->service) {
випадки "kickbox":
$emailValidationContext->setEmailValidator(новий KickboxService());
break;
case 'zerobounce':
$emailValidationContext->setEmailValidator(новий ZeroBounceService());
break;
case 'перевірка користувача':
$emailValidationContext->setEmailValidator(new UsercheckService());
break;
за замовчуванням:
throw new \Exception("Служба перевірки не підтримується.");
}
// перевірка електронної пошти за допомогою служби
return $emailValidationContext->validate($request->email);
}
}
пільги
1. Гнучкість і розширюваність
Шаблон стратегії дозволяє легко додавати нові стратегії, не змінюючи існуючий код. Наприклад, якщо вам потрібно додати нову службу перевірки, ви просто створюєте новий клас, який її реалізує EmailValidationServiceInterface
і ввести його в контекст.
2. Дотримання принципів SOLID
- Відкритий/закритий принцип : система відкрита для розширень, але закрита для модифікацій, що дозволяє розширювати функціональність без зміни існуючого коду.
- Принцип єдиної відповідальності : Кожен клас несе відповідальність, що полегшує його підтримку та тестування.
3. Усунення умовної логіки
Ця модель позбавляє від необхідності складних інструкцій if-else
, switch
зробити код чистішим і читабельнішим.
Більше прикладів
Ви також можете використовувати шаблони проектування стратегії для інших випадків використання, наприклад обробки замовлень за допомогою різних платіжних шлюзів на платформі електронної комерції. Наприклад, ви можете мати PayPal, Stripe, BankTransfer тощо або використовувати різні служби доставки електронної пошти, Mailgun, SendingBlue, SMTP тощо.