Коротка відповідь
middleStrategy — це паттерн поведінки, який дозволяє визначити сімейство алгоритмів, інкапсулювати кожен з них і робити їх взаємозамінними. У контексті використовується інтерфейс `Strategy`, а конкретні реалізації (наприклад, `FastSort`, `StableSort`) передаються через конструктор або setter. Приклад: `const sorter = new Sorter(new QuickSort()); const result = sorter.sort(data);`
Повне пояснення
1. Що це і навіщо
Strategy – паттерн поведінки (GoF), що дозволяє змінювати алгоритм у runtime, не модифікуючи клієнтський код. Використовується там, де потрібна гнучкість вибору алгоритму (сортування, пошук, обчислення ціни тощо).
2. Принцип роботи / алгоритм
Паттерн складається з трьох ролей: Context (клієнт), який використовує стратегічний інтерфейс; Strategy – абстрактний тип, що визначає метод execute; і конкретні реалізації (ConcreteStrategyA, ConcreteStrategyB). Клієнт отримує об’єкт Context і передає йому конкретну стратегічну реалізацію, після чого викликає context.execute().
3. Реалізація (JS / TS)
Базова реалізація:
interface Strategy { execute(a: number, b: number): number; }
class Add implements Strategy { execute(a,b){return a+b;} }
class Subtract implements Strategy { execute(a,b){return a-b;} }
class Context{ constructor(private strategy:Strategy){}
setStrategy(s:Strategy){this.strategy=s;}
run(a:number,b:number){return this.strategy.execute(a,b);} }
Реалістичний приклад (веб‑dev):
// Сортування таблиці
class SortContext{ constructor(private strategy:SortStrategy){}
sort(data){return this.strategy.sort(data);} }
class QuickSort implements SortStrategy{ sort(d){/* швидке сортування */} }
const ctx = new SortContext(new QuickSort());
Спрощений для новачка:
const strategies = {
inc: (x)=>x+1,
dec: (x)=>x-1
};
function apply(strategyName, val){return strategies[strategyName](val);}
4. Тестування (Jest або Vitest)
test('Strategy adds correctly', () => {
const ctx = new Context(new Add());
expect(ctx.run(2,3)).toBe(5);
});
5. Проблеми та edge cases
- Неправильне використання ролей – передача
ContextзамістьStrategy. 2. Зайва абстракція – створення стратегії для простого алгоритму, що лише обгортає функцію. 3. Cyclical dependencies – стратегія залежить від контексту, що створює замикання. 4. Плутанина між подібними паттернами – змішування Strategy з Template Method. 5. Performance‑пастки – створення нових об’єктів стратегії на кожен виклик замість кешування.
6. Оптимізація та продуктивність
Стратегія не додає значної накладної пам’яті, але кожен об’єкт стратегії створюється окремо. Якщо алгоритм статичний, краще використовувати функції замість класів. Перевага – швидка зміна поведінки без рефакторингу.
7. Без JS / архітектурні альтернативи
У чистій HTML/CSS можна реалізувати «стратегію» через CSS‑клас, що змінює стиль елемента. У бекенді без паттерна можна просто передавати функцію як колбек.
8. Cheatsheet + follow-up
- Cheatsheet:
Context→Strategyinterface → concrete strategies. - Interview question 1: Як Strategy допомагає уникнути умовних операторів у коді?
- Interview question 2: Які ризики виникають при створенні нових стратегій під час кожного виклику?