Знаєте як перекладається strategy? ага, да стратегія. А що таке стратегія?
Якщо говорити про шаблон проектування, то це класичний патерн, суть якого зводиться до того, щоб визначити певні сімейства алгоритмів і інкапсулювати їх в окремому класі.
Але я ж люблю прості приклади, з життя, тому давайте глянем що таке стратегія в звичайному житті. Мені подобається таке визначення:
Стратегія – план досягнення мети.
Навколо цього і будуватимемо наш приклад для реалізації стратегії.
Приклад з життя
Уявімо що ми бідний студент, який живе на краю міста, і якому потрібно дістатися до свого університету. Які варіанти ми маємо?
- Піти пішки
- Поїхати на таксі
- Громадський транспорт
Як бачимо, мета одна, статегій багато. Кожна з них має свої певні параметри, якими її можна описати: наприклад, час, вартість.
Відповідно, якби ми намагались запрограмувати таку поведінку, у нас було б щось схоже на це:
// стратегія - це СПОСІБ як саме
interface TravelStrategy
{
public function travel(): string;
public function getTime(): int;
public function getCost(): int;
}
// Стратегія 1: Пішки
class WalkStrategy implements TravelStrategy
{
public function travel(): string
{
return "🚶 Йду пішки";
}
public function getTime(): int
{
return 40;
}
public function getCost(): int
{
return 0;
}
}
// Стратегія 2: Автобус
class BusStrategy implements TravelStrategy
{
public function travel(): string
{
return "🚌 Їду автобусом";
}
public function getTime(): int
{
return 20;
}
public function getCost(): int
{
return 8;
}
}
// Стратегія 3: Таксі
class TaxiStrategy implements TravelStrategy
{
public function travel(): string
{
return "🚕 Їду таксі";
}
public function getTime(): int
{
return 10;
}
public function getCost(): int
{
return 150;
}
}
// Клас "Дорога до універу"
class GoToUniversity
{
private ?TravelStrategy $strategy = null;
public function chooseWay(TravelStrategy $strategy): void
{
$this->strategy = $strategy;
}
public function go(): void
{
echo $this->strategy->travel() . "\n";
echo "Час: {$this->strategy->getTime()} хв\n";
echo "Вартість: {$this->strategy->getCost()} грн\n";
}
}
// === ВИКОРИСТАННЯ ===
$trip = new GoToUniversity();
echo "Ситуація: проспав, грошей мало\n";
$trip->chooseWay(new BusStrategy());
$trip->go();
echo "Ситуація: маю час, економлю гроші\n";
$trip->chooseWay(new WalkStrategy());
$trip->go();
echo "Ситуація: контрольна за 5 хв, є гроші\n";
$trip->chooseWay(new TaxiStrategy());
$trip->go();
Коли використовувати
Коли явно видно різні алгоритми для виконання одної і тої самої задачі
- Системи розрахунку вартості доставки (укрпошта, нова пошта, самовивіз)
- Системи розрахунку податків (різні країни, різні ставки)
- Логіка імпоту та екпорту (можна це робити в різних форматах)
Насправді її можна використовувати замість будь-якого if/else в коді, але зрозуміло що так ніхто не робить. Тому тут важливо зрозуміти місця в коді, які можуть бути розширені в майбутньому і викоремити реалізацію стратегій в окремі класи, а в момент розширення – створювати нові класи.