Kiedy używać Strategy, a kiedy Strategy + Factory?
https://copilot.microsoft.com/chats/EMe1TGXmJQNXbjW72sB2N
Praktyczny przewodnik z przykładową strukturą plików (WordPress‑friendly)
W świecie backendu często pojawia się problem:
„Mam kilka wersji algorytmu i chcę łatwo przełączać się między nimi — bez if‑ów, bez bałaganu i bez ryzyka popsucia starego kodu.”
To właśnie moment, w którym błyszczy duet:
- Strategy — różne algorytmy pod wspólnym interfejsem
- Factory — wybór właściwego algorytmu po nazwie
W tym wpisie pokazuję:
- kiedy wystarczy sam Strategy,
- kiedy konieczne jest Strategy + Factory,
- jak wygląda praktyczna struktura plików,
- jak to działa w API (np. Flask).
🔹 Strategy — kiedy wystarczy?
Wzorzec Strategy rozwiązuje jeden problem:
„Chcę mieć różne implementacje tego samego algorytmu.”
Przykład:
class BaseStrategy:
def analyze(self, df):
raise NotImplementedError
class StrategyV1(BaseStrategy):
def analyze(self, df):
...
class StrategyV2(BaseStrategy):
def analyze(self, df):
...
Użycie:
strategy = StrategyV2()
strategy.analyze(df)
✔ Kiedy Strategy jest OK?
- masz 1–2 strategie,
- wybór strategii jest na stałe w kodzie,
- nie planujesz dynamicznego przełączania,
- nie planujesz wersjonowania algorytmów.
❌ Kiedy Strategy zaczyna przeszkadzać?
- gdy pojawia się 3, 5, 10 strategii,
- gdy chcesz wersjonować algorytmy (
v1,v2,v3), - gdy wybór strategii ma pochodzić z API / UI / bazy danych,
- gdy chcesz dodawać nowe strategie bez dotykania starego kodu.
Wtedy Strategy samo nie wystarcza.
🔹 Strategy + Factory — kiedy to konieczne?
Strategy mówi jak wykonać algorytm. Factory mówi którą strategię wybrać.
To dwa różne problemy.
🔥 Kluczowa idea
Każda strategia ma własne name:
class StrategyV2(BaseStrategy):
name = "strat_v2"
Rejestr przechowuje je w słowniku:
STRATEGY_REGISTRY = {
"strat_v1": StrategyV1,
"strat_v2": StrategyV2,
}
Fabryka wybiera strategię po nazwie:
strategy = get_strategy("strat_v2")
I to jest moment, w którym system staje się plug‑and‑play.
📁 Struktura plików
analysis/
__init__.py
base.py
registry.py
factory.py
strategies/
__init__.py
strategia_podstawowa.py
strategia_podstawowa_v2.py
strategia_podstawowa_v3.py
strategia_eksperymentalna.py
🔹 base.py — interfejs strategii
class BaseAnalysisStrategy:
name: str
def analyze(self, df, **params):
raise NotImplementedError
🔹 registry.py — automatyczny rejestr strategii
STRATEGY_REGISTRY = {}
def register_strategy(cls):
STRATEGY_REGISTRY[cls.name] = cls
return cls
🔹 factory.py — wybór strategii po nazwie
from .registry import STRATEGY_REGISTRY
def get_strategy(name: str):
return STRATEGY_REGISTRY[name]()
🔹 strategia_podstawowa_v2.py — przykładowa strategia
@register_strategy #wymagane do zarejestrowania strategii w słowniku STRATEGY_REGISTRY
class StrategiaPodstawowaV2(BaseAnalysisStrategy):
name = "strat_pods_v2"
def analyze(self, df, **params):
...
🔥 Co daje Strategy + Factory?
1. Dodajesz nową strategię → dodajesz nowy plik → koniec
strategies/
strategia_podstawowa_v4.py
Nadajesz:
name = "strat_pods_v4"
I już możesz:
get_strategy("strat_pods_v4")
2. Zero if‑ów
Nie ma:
if typ == "v1":
...
elif typ == "v2":
...
Fabryka robi to za Ciebie.
3. Idealne do API (Flask, FastAPI)
Użytkownik wybiera strategię:
wybrana = request.form.get("user_strategy", "strat_pods_v1")
wynik = get_strategy(wybrana).analyze(df)
4. Idealne do wersjonowania algorytmów
strat_pods_v1strat_pods_v2strat_pods_v3strat_pods_experimental
5. Zgodne z Open/Closed Principle
System jest:
- otwarty na rozszerzenia (dodajesz nowe strategie),
- zamknięty na modyfikacje (nie dotykasz starego kodu).
🧪 Przykład użycia w Flask
@app.route("/analiza", methods=["POST"])
def analiza():
wybrana = request.form.get("user_strategy", "strat_pods_v1")
df = pobierz_dane()
strategia = get_strategy(wybrana)
wynik = strategia.analyze(df, prog=10, margines=5)
return jsonify(wynik.to_dict(orient="records"))
🔥 Podsumowanie
Strategy wystarczy, gdy:
- masz mało strategii,
- wybór jest statyczny,
- nie planujesz rozwoju.
Strategy + Factory jest konieczne, gdy:
- strategie mają rosnąć,
- wybór ma być dynamiczny,
- chcesz wersjonować algorytmy,
- chcesz architekturę pluginów,
- chcesz czysty kod bez if‑ów.
📌 Wniosek do zapamiętania
Strategy = różne algorytmy. Factory = wybór algorytmu. Razem = system, który rośnie bez bólu.