{"id":377,"date":"2026-06-09T13:55:16","date_gmt":"2026-06-09T11:55:16","guid":{"rendered":"https:\/\/blog.ctr24.co.pl\/?p=377"},"modified":"2026-06-09T14:02:09","modified_gmt":"2026-06-09T12:02:09","slug":"kiedy-uzywac-strategy-a-kiedy-strategy-factory","status":"publish","type":"post","link":"https:\/\/blog.ctr24.co.pl\/?p=377","title":{"rendered":"Kiedy u\u017cywa\u0107 Strategy, a kiedy Strategy + Factory?"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/copilot.microsoft.com\/chats\/EMe1TGXmJQNXbjW72sB2N\">https:\/\/copilot.microsoft.com\/chats\/EMe1TGXmJQNXbjW72sB2N<\/a><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Praktyczny przewodnik z przyk\u0142adow\u0105 struktur\u0105 plik\u00f3w (WordPress\u2011friendly)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">W \u015bwiecie backendu cz\u0119sto pojawia si\u0119 problem:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u201eMam kilka wersji algorytmu i chc\u0119 \u0142atwo prze\u0142\u0105cza\u0107 si\u0119 mi\u0119dzy nimi \u2014 bez if\u2011\u00f3w, bez ba\u0142aganu i bez ryzyka popsucia starego kodu.\u201d<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">To w\u0142a\u015bnie moment, w kt\u00f3rym b\u0142yszczy duet:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Strategy<\/strong> \u2014 r\u00f3\u017cne algorytmy pod wsp\u00f3lnym interfejsem<\/li>\n\n\n\n<li><strong>Factory<\/strong> \u2014 wyb\u00f3r w\u0142a\u015bciwego algorytmu po nazwie<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">W tym wpisie pokazuj\u0119:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>kiedy wystarczy sam Strategy,<\/li>\n\n\n\n<li>kiedy konieczne jest Strategy + Factory,<\/li>\n\n\n\n<li>jak wygl\u0105da <strong>praktyczna struktura plik\u00f3w<\/strong>,<\/li>\n\n\n\n<li>jak to dzia\u0142a w API (np. Flask).<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udd39 Strategy \u2014 kiedy wystarczy?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Wzorzec Strategy rozwi\u0105zuje jeden problem:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">\u201eChc\u0119 mie\u0107 r\u00f3\u017cne implementacje tego samego algorytmu.\u201d<\/p>\n<\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Przyk\u0142ad:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class BaseStrategy:\n    def analyze(self, df):\n        raise NotImplementedError\n\nclass StrategyV1(BaseStrategy):\n    def analyze(self, df):\n        ...\n\nclass StrategyV2(BaseStrategy):\n    def analyze(self, df):\n        ...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">U\u017cycie:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>strategy = StrategyV2()\nstrategy.analyze(df)\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">\u2714 Kiedy Strategy jest OK?<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>masz 1\u20132 strategie,<\/li>\n\n\n\n<li>wyb\u00f3r strategii jest na sta\u0142e w kodzie,<\/li>\n\n\n\n<li>nie planujesz dynamicznego prze\u0142\u0105czania,<\/li>\n\n\n\n<li>nie planujesz wersjonowania algorytm\u00f3w.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">\u274c Kiedy Strategy zaczyna przeszkadza\u0107?<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>gdy pojawia si\u0119 3, 5, 10 strategii,<\/li>\n\n\n\n<li>gdy chcesz wersjonowa\u0107 algorytmy (<code>v1<\/code>, <code>v2<\/code>, <code>v3<\/code>),<\/li>\n\n\n\n<li>gdy wyb\u00f3r strategii ma pochodzi\u0107 z API \/ UI \/ bazy danych,<\/li>\n\n\n\n<li>gdy chcesz dodawa\u0107 nowe strategie bez dotykania starego kodu.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Wtedy Strategy samo nie wystarcza.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83d\udd39 Strategy + Factory \u2014 kiedy to konieczne?<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Strategy m\u00f3wi <em>jak<\/em> wykona\u0107 algorytm. Factory m\u00f3wi <em>kt\u00f3r\u0105 strategi\u0119 wybra\u0107<\/em>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To dwa r\u00f3\u017cne problemy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udd25 Kluczowa idea<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Ka\u017cda strategia ma w\u0142asne <code>name<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class StrategyV2(BaseStrategy):\n    name = \"strat_v2\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Rejestr przechowuje je w s\u0142owniku:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>STRATEGY_REGISTRY = {\n    \"strat_v1\": StrategyV1,\n    \"strat_v2\": StrategyV2,\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Fabryka wybiera strategi\u0119 po nazwie:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>strategy = get_strategy(\"strat_v2\")\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I to jest moment, w kt\u00f3rym system staje si\u0119 <strong>plug\u2011and\u2011play<\/strong>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83d\udcc1 Struktura plik\u00f3w<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>analysis\/\n    __init__.py\n    base.py\n    registry.py\n    factory.py\n    strategies\/\n        __init__.py\n        strategia_podstawowa.py\n        strategia_podstawowa_v2.py\n        strategia_podstawowa_v3.py\n        strategia_eksperymentalna.py\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udd39 base.py \u2014 interfejs strategii<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>class BaseAnalysisStrategy:\n    name: str\n\n    def analyze(self, df, **params):\n        raise NotImplementedError\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udd39 registry.py \u2014 automatyczny rejestr strategii<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>STRATEGY_REGISTRY = {}\n\ndef register_strategy(cls):\n    STRATEGY_REGISTRY&#91;cls.name] = cls\n    return cls\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udd39 factory.py \u2014 wyb\u00f3r strategii po nazwie<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>from .registry import STRATEGY_REGISTRY\n\ndef get_strategy(name: str):\n    return STRATEGY_REGISTRY&#91;name]()\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">\ud83d\udd39 strategia_podstawowa_v2.py \u2014 przyk\u0142adowa strategia<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>@register_strategy #wymagane do zarejestrowania strategii w s\u0142owniku STRATEGY_REGISTRY\nclass StrategiaPodstawowaV2(BaseAnalysisStrategy):\n    name = \"strat_pods_v2\"\n\n    def analyze(self, df, **params):\n        ...\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83d\udd25 Co daje Strategy + Factory?<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">1. Dodajesz now\u0105 strategi\u0119 \u2192 dodajesz nowy plik \u2192 koniec<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>strategies\/\n    strategia_podstawowa_v4.py\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Nadajesz:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>name = \"strat_pods_v4\"\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">I ju\u017c mo\u017cesz:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>get_strategy(\"strat_pods_v4\")\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">2. Zero if\u2011\u00f3w<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Nie ma:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>if typ == \"v1\":\n    ...\nelif typ == \"v2\":\n    ...\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Fabryka robi to za Ciebie.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Idealne do API (Flask, FastAPI)<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">U\u017cytkownik wybiera strategi\u0119:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>wybrana = request.form.get(\"user_strategy\", \"strat_pods_v1\")\nwynik = get_strategy(wybrana).analyze(df)\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">4. Idealne do wersjonowania algorytm\u00f3w<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>strat_pods_v1<\/code><\/li>\n\n\n\n<li><code>strat_pods_v2<\/code><\/li>\n\n\n\n<li><code>strat_pods_v3<\/code><\/li>\n\n\n\n<li><code>strat_pods_experimental<\/code><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">5. Zgodne z Open\/Closed Principle<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">System jest:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>otwarty na rozszerzenia<\/strong> (dodajesz nowe strategie),<\/li>\n\n\n\n<li><strong>zamkni\u0119ty na modyfikacje<\/strong> (nie dotykasz starego kodu).<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83e\uddea Przyk\u0142ad u\u017cycia w Flask<\/h1>\n\n\n\n<pre class=\"wp-block-code\"><code>@app.route(\"\/analiza\", methods=&#91;\"POST\"])\ndef analiza():\n    wybrana = request.form.get(\"user_strategy\", \"strat_pods_v1\")\n\n    df = pobierz_dane()\n    strategia = get_strategy(wybrana)\n\n    wynik = strategia.analyze(df, prog=10, margines=5)\n\n    return jsonify(wynik.to_dict(orient=\"records\"))\n<\/code><\/pre>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83d\udd25 Podsumowanie<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Strategy wystarczy, gdy:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>masz ma\u0142o strategii,<\/li>\n\n\n\n<li>wyb\u00f3r jest statyczny,<\/li>\n\n\n\n<li>nie planujesz rozwoju.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Strategy + Factory jest konieczne, gdy:<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>strategie maj\u0105 rosn\u0105\u0107,<\/li>\n\n\n\n<li>wyb\u00f3r ma by\u0107 dynamiczny,<\/li>\n\n\n\n<li>chcesz wersjonowa\u0107 algorytmy,<\/li>\n\n\n\n<li>chcesz architektur\u0119 plugin\u00f3w,<\/li>\n\n\n\n<li>chcesz czysty kod bez if\u2011\u00f3w.<\/li>\n<\/ul>\n\n\n\n<h1 class=\"wp-block-heading\">\ud83d\udccc Wniosek do zapami\u0119tania<\/h1>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\"><strong>Strategy = r\u00f3\u017cne algorytmy.<\/strong> <strong>Factory = wyb\u00f3r algorytmu.<\/strong> <strong>Razem = system, kt\u00f3ry ro\u015bnie bez b\u00f3lu.<\/strong><\/p>\n<\/blockquote>\n","protected":false},"excerpt":{"rendered":"<p>https:\/\/copilot.microsoft.com\/chats\/EMe1TGXmJQNXbjW72sB2N Praktyczny przewodnik z przyk\u0142adow\u0105 struktur\u0105 plik\u00f3w (WordPress\u2011friendly) W \u015bwiecie backendu cz\u0119sto pojawia si\u0119 problem: \u201eMam kilka wersji algorytmu i<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,19],"tags":[],"class_list":["post-377","post","type-post","status-publish","format-standard","hentry","category-python","category-tips"],"_links":{"self":[{"href":"https:\/\/blog.ctr24.co.pl\/index.php?rest_route=\/wp\/v2\/posts\/377","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ctr24.co.pl\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ctr24.co.pl\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ctr24.co.pl\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ctr24.co.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=377"}],"version-history":[{"count":3,"href":"https:\/\/blog.ctr24.co.pl\/index.php?rest_route=\/wp\/v2\/posts\/377\/revisions"}],"predecessor-version":[{"id":381,"href":"https:\/\/blog.ctr24.co.pl\/index.php?rest_route=\/wp\/v2\/posts\/377\/revisions\/381"}],"wp:attachment":[{"href":"https:\/\/blog.ctr24.co.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=377"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ctr24.co.pl\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=377"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ctr24.co.pl\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=377"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}