Strategy — co to je, vzor strategie v iOS a Android

Autor: IT Sectr Publikováno: 2026-02-18 Doba čtení: 9 min

Strategy (Strategie) — behaviorální návrhový vzor, který definuje rodinu zaměnitelných algoritmů a umísťuje každý z nich do samostatné třídy (Strategy). Vzor umožňuje vybrat algoritmus za běhu: klientský kód pracuje přes společný rozhraní Strategy a konkrétní implementace se dosazuje v runtime. V iOS se vzor implementuje přes Protocol + třídy strategie, v Android — přes Interface + implementace. Strategy — jeden z 23 vzorů GoF, široce používaný pro zpracování plateb, validaci, třídění a filtrování dat. Více — v originálním popisu GoF.

Hlavní body

  • Strategy — behaviorální vzor GoF pro rodinu zaměnitelných algoritmů
  • Zapouzdření algoritmů — každý algoritmus je izolován ve vlastní třídě
  • Rozhraní Strategy — společná smlouva, kterou implementují všechny konkrétní strategie
  • Kompozice místo dědičnosti — kontext uchovává odkaz na strategii, nedědí chování
  • Princip Open/Closed — nové strategie se přidávají bez změny existujícího kódu

Co je vzor Strategy: podstata a struktura

Strategy — jeden z 23 vzorů GoF (Gang of Four), popsaný v knize «Design Patterns: Elements of Reusable Object-Oriented Software» (1994). Vzor řeší problém výběru algoritmu za běhu. Místo psaní jedné třídy s mnoha podmíněnými operátory (if-else, switch) Strategy navrhuje oddělit každý algoritmus do samostatné třídy se společným rozhraním. Kontext (třída používající strategii) uchovává odkaz na rozhraní Strategy a deleguje provedení na konkrétní strategii.

Struktura vzoru zahrnuje tři prvky: Context (kontext) obsahuje odkaz na Strategy a volá její metodu; Strategy (rozhraní) deklaruje společnou metodu pro všechny algoritmy; ConcreteStrategy (konkrétní strategie) implementuje rozhraní a obsahuje konkrétní algoritmus. Klient vytvoří požadovanou strategii a předá ji kontextu přes konstruktor, setter nebo parametr metody. Kontext neví, která strategie se provádí — pracuje pouze s rozhraním.

KomponentaRolePříklad
ContextObsahuje odkaz na StrategyPaymentProcessor, Sorter
StrategySpolečné rozhraní pro algoritmyProtocol PaymentStrategy
ConcreteStrategyKonkrétní implementace algoritmuCardPayment, PayPalPayment

Princip Open/Closed — hlavní výhoda Strategy. Systém je otevřený pro rozšíření (lze přidat novou strategii) a uzavřený pro změnu (není třeba měnit kód kontextu). Bez vzoru vyžaduje přidání nového algoritmu změnu existující třídy, což porušuje OCP a zvyšuje riziko regresních chyb. Strategy také zmenšuje velikost tříd: místo 200řádkové třídy se switch-case získáte 6 tříd po 20 řádcích.

Strategy v iOS: implementace ve Swift s Protocol

Strategy ve Swift se implementuje přes Protocol (rozhraní strategie) a třídy nebo struktury strategie. Swift protokoly podporují associated types a generic constraints, což poskytuje flexibilitu při navrhování strategií. Kontext je obvykle třída ViewModel nebo služba, která přijímá strategii v init nebo přes vlastnost. Vzor je široce používán v iOS projektech pro zpracování událostí, animace, formátování dat a UI strategie.

swift
// 1. Protocol Strategy
protocol PaymentStrategy {
    func pay(amount: Decimal) async throws -> PaymentResult
}

// 2. Konkrétní strategie
struct CardPaymentStrategy: PaymentStrategy {
    let cardNumber: String
    let cvv: String

    func pay(amount: Decimal) async throws -> PaymentResult {
        // Odeslání požadavku na bankovní API
        return PaymentResult(status: .success, transactionId: "tx_\(UUID())")
    }
}

struct PayPalPaymentStrategy: PaymentStrategy {
    let email: String

    func pay(amount: Decimal) async throws -> PaymentResult {
        // Přesměrování na PayPal SDK
        return PaymentResult(status: .success, transactionId: "pp_\(UUID())")
    }
}

// 3. Context
class PaymentProcessor {
    private var strategy: PaymentStrategy

    init(strategy: PaymentStrategy) {
        self.strategy = strategy
    }

    func setStrategy(_: PaymentStrategy) {
        strategy = strategy
    }

    func processPayment(amount: Decimal) async throws -> PaymentResult {
        return try await strategy.pay(amount: amount)
    }
}

// Použití
let processor = PaymentProcessor(strategy: CardPaymentStrategy(cardNumber: "4111...", cvv: "123"))
let result = try await processor.processPayment(amount: 99.99)

Strategy ve SwiftUI — vzor se přirozeně integruje s MVVM. ViewModel obsahuje vlastnost strategie a volá její metodu při akci uživatele. SwiftUI View přijímá data přes @Published nebo @State — strategie skrývá detaily implementace před View. Například strategie validace textu (emailValidator, phoneValidator) se mění podle typu vstupního pole. Kombinace Strategy se SwiftUI poskytuje flexibilitu bez dědičnosti od UIKit.

Strategy v Android: implementace v Kotlin s Interface

Strategy v Kotlin používá Interface na úrovni jazyka a funkcionální rozhraní (SAM) pro zjednodušení. Kotlin podporuje lambdy, což umožňuje předávat algoritmy jako funkce bez deklarace samostatné třídy strategie. V Android se vzor aplikuje ve ViewModel a Use Cases pro izolaci algoritmů načítání dat, ukládání do mezipaměti a zpracování chyb. Android projekty s Clean Architecture používají Strategy pro injektování různých implementací repository podle příznaků (mock, real, cache).

kotlin
// 1. Interface Strategy
interface PaymentStrategy {
    suspend fun pay(amount: BigDecimal): PaymentResult
}

// 2. Konkrétní strategie
class CardPaymentStrategy(
    private val cardNumber: String,
    private val cvv: String
) : PaymentStrategy {
    override suspend fun pay(amount: BigDecimal): PaymentResult {
        // Bankovní API přes Retrofit
        return PaymentResult(success = true, transactionId = "tx_${UUID.randomUUID()}")
    }
}

class PayPalPaymentStrategy(
    private val email: String
) : PaymentStrategy {
    override suspend fun pay(amount: BigDecimal): PaymentResult {
        // PayPal SDK integration
        return PaymentResult(success = true, transactionId = "pp_${UUID.randomUUID()}")
    }
}

// 3. Context
class PaymentProcessor(
    private val strategy: PaymentStrategy
) {
    fun setStrategy(strategy: PaymentStrategy): PaymentProcessor {
        return PaymentProcessor(strategy)
    }

    suspend fun processPayment(amount: BigDecimal): PaymentResult {
        return strategy.pay(amount)
    }
}

// Použití ve ViewModel
class CheckoutViewModel : ViewModel() {
    private var processor = PaymentProcessor(CardPaymentStrategy("4111...", "123"))

    fun payWithCard() {
        viewModelScope.launch {
            val result = processor.processPayment(BigDecimal("99.99"))
            // Zpracování výsledku
        }
    }
}

Strategy s Hilt/Dagger — v Android projektech jsou strategie často injektovány přes DI. Hilt poskytuje konkrétní implementaci PaymentStrategy přes @Binds nebo @Provides. To umožňuje měnit strategii bez změny kódu kontextu — stačí změnit DI modul pro jiné sestavení (debug/release). Například pro ladění se injektuje MockPaymentStrategy, pro produkci — skutečná bankovní strategie. Kombinace Strategy + DI poskytuje maximální flexibilitu.

Srovnání Strategy se State, Command a Template Method

Strategy vs State — strukturálně jsou vzory identické: oba používají kompozici s rozhraním a konkrétními třídami. Rozdíl je v účelu: Strategy vybírá nezávislý algoritmus, State řídí chování objektu podle jeho stavu. Ve State kontext sám mění strategii při změně stavu, v Strategy kontext neřídí přepínání — klient explicitně určuje algoritmus. Strategie o sobě navzájem nevědí, stavy do sebe mohou přecházet.

Strategy vs Command — Command zapouzdřuje jedinou akci jako objekt, Strategy zapouzdřuje sadu zaměnitelných algoritmů. Command — «co udělat» (jedno volání execute), Strategy — «jak udělat» (algoritmus z několika kroků). Command se používá pro fronty, odložené provedení, undo/redo. Strategy — pro výběr způsobu provedení úkolu za běhu. Příkazy lze parametrizovat strategiemi, kombinací obou vzorů.

CharakteristikaStrategyStateCommandTemplate Method
ÚčelZaměnitelné algoritmyChování podle stavuZapouzdření požadavkuKostra algoritmu
ZměnaExplicitně klientemAutomaticky kontextemKlientem nebo frontouDědičností
ÚroveňObjektová (kompozice)Objektová (kompozice)ObjektováTřídní (dědičnost)

Strategy vs Template Method — oba vzory definují algoritmy, ale různými způsoby. Template Method používá dědičnost: základní třída definuje kostru algoritmu (šablonovou metodu), podtřídy přepisují jednotlivé kroky. Strategy používá kompozici: algoritmus je zcela vyčleněn do samostatné třídy. Template Method je jednodušší pro případy s pevnou strukturou algoritmu, Strategy — když jsou algoritmy zcela odlišné a mohou se dynamicky měnit.

Reálné příklady použití vzoru Strategy

Zpracování plateb — klasický příklad Strategy. Nákupní košík internetového obchodu obsahuje seznam produktů a způsob platby volí uživatel. Každý způsob (karta, PayPal, Apple Pay, Google Pay, kryptoměna) — samostatná strategie se společným podpisem pay(amount). Kontext PaymentProcessor neví, jak přesně se platba provádí — volá společnou metodu. Přidání nového způsobu platby nevyžaduje změnu kódu košíku.

Validace dat — Strategy se aplikuje pro různá pravidla validace stejného pole. EmailValidatorStrategy, PhoneValidatorStrategy, AgeValidatorStrategy implementují společné rozhraní ValidationStrategy s metodou validate(input). Registrační formulář používá sadu strategií pro kontrolu každého pole. Validační strategie lze kombinovat do řetězce (Chain of Responsibility) nebo aplikovat všechny najednou v cyklu. To nahrazuje dlouhé kontroly if-else kolekcí polymorfních validátorů.

swift
// Strategie třídění
protocol SortingStrategy {
    func sort<T>(_ items: [T]) -> [T] where T: Comparable
}

struct QuickSortStrategy: SortingStrategy {
    func sort<T>(_ items: [T]) -> [T] { /* quicksort */ items }
}

struct MergeSortStrategy: SortingStrategy {
    func sort<T>(_ items: [T]) -> [T] { /* mergesort */ items }
}

class SortedDataSource<T> {
    private var strategy: SortingStrategy
    func display(_ items: [T]) { let sorted = strategy.sort(items) }
}

Autentizace — v mobilních aplikacích se autentizační strategie přepínají podle poskytovatele. AuthStrategy s metodami login(), logout(), getToken() je implementována pro EmailPasswordAuth, GoogleAuth, AppleAuth, BiometricAuth. Kontext AuthManager přijímá strategii přes DI nebo továrnu. To umožňuje přidávat nové poskytovatele autentizace bez změny přihlašovací obrazovky. Vzor Strategy — základ mnoha OAuth knihoven a Firebase Authentication.

Často kladené otázky

Kdy použít Strategy místo if-else?

Strategy je opodstatněný, když máte 3+ algoritmů, které se mohou měnit nebo rozšiřovat. Pokud jsou algoritmy 2 a stabilní — jednoduchý if-else je méně náročný. Použijte Strategy, když se algoritmy používají v různých částech aplikace, když je potřeba nahrazovat algoritmy za běhu nebo když každý algoritmus vyžaduje vlastní závislosti a testy.

Je Strategy to samé jako State?

Ne, jsou to různé vzory s podobnou strukturou. Strategy — klient explicitně vybírá algoritmus a strategie jsou nezávislé. State — objekt sám mění své chování při změně vnitřního stavu a stavy mohou do sebe přecházet. Ve State kontext řídí změnu stavu, v Strategy — klientský kód.

Lze Strategy použít bez tříd — přes closures?

Ano, ve Swift a Kotlin lze strategii předat jako closure nebo lambdu. Swift: typealias PaymentHandler = (Decimal) async throws -> PaymentResult. Kotlin: typealias PaymentFun = suspend (BigDecimal) -> PaymentResult. To zjednodušuje kód pro jednoduché případy, ale ztrácí se pojmenování a dokumentace. Pro 1-2 algoritmy — closure stačí, pro 4+ — jsou lepší samostatné třídy.

Jak testovat vzor Strategy?

Každá strategie se testuje samostatným unit testem s mock závislostmi. Kontext se testuje s mock strategií — ověřuje se, že kontext volá metodu strategie a předává správné parametry. Ve Swift použijte XCTest + protokoly pro mock, v Kotlin — MockK nebo Mockito. Hlavní výhoda: každá strategie se testuje izolovaně bez složité konfigurace.

Je Strategy vzor GoF?

Ano, Strategy (Strategie) — jeden z 23 vzorů popsaných v knize «Design Patterns: Elements of Reusable Object-Oriented Software» (Gamma, Helm, Johnson, Vlissides, 1994). Patří do skupiny behaviorálních vzorů (Behavioral Patterns). Synonyma: Policy (Politika). Původní příkladový kód v Smalltalk-80 je dostupný v původním vydání GoF.

Shrnutí

  • Strategy — behaviorální vzor pro zaměnitelné algoritmy se společným rozhraním
  • Zapouzdření — každý algoritmus je izolován v samostatné třídě strategie
  • iOS Swift — implementace přes Protocol, struktury a closures
  • Android Kotlin — implementace přes Interface, lambdy a DI s Hilt
  • Open/Closed princip — nové strategie se přidávají bez změny kontextu
  • Použití — platby, validace, třídění, autentizace, formátování

Vyvineme mobilní aplikaci na klíč

IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.

Prodiskutovat projekt

Přečtěte si také