Dlaczego Strategy pattern jest ważny?
W prawdziwych aplikacjach często mamy sytuacje gdzie ten sam problem można rozwiązać na kilka sposobów. Na przykład – sortowanie listy może odbywać się przez bubble sort, quick sort czy merge sort. Bez Strategy pattern kod szybko staje się nieczytelny przez mnogie instrukcje if-else lub switch.
Strategy pattern rozwiązuje ten problem przez separację algorytmu od kodu który go używa. To znacznie ułatwia dodawanie nowych algorytmów i testowanie różnych approaches.
Co się nauczysz:
- Jak zaimplementować Strategy pattern w Javie 8
- Kiedy używać tego wzorca w prawdziwych projektach
- Jak uniknąć typowych błędów przy implementacji
- Różnice między Strategy a innymi wzorcami behawioralnymi
- Praktyczne przykłady z e-commerce i systemów płatności
Wymagania wstępne:
- Znajomość podstaw Javy 8 (klasy, interfejsy, lambda expressions)
- Podstawowe zrozumienie wzorców projektowych
- Doświadczenie z programowaniem obiektowym
Czym jest Strategy pattern?
Strategy pattern to wzorzec behawioralny który definiuje rodzinę algorytmów, enkapsuluje każdy z nich w osobnej klasie i czyni je wymienialnymi. Kluczowe komponenty to:
Strategy – interfejs definiujący wspólny kontrakt
ConcreteStrategy – konkretne implementacje algorytmów
Implementacja w Javie 8
Pokażmy praktyczny przykład z systemem obliczania rabatów w sklepie internetowym:
// Interfejs strategii public interface DiscountStrategy { double calculateDiscount(double amount); } // Konkretne strategie public class RegularCustomerDiscount implements DiscountStrategy { @Override public double calculateDiscount(double amount) { return amount * 0.05; // 5% rabatu } } public class PremiumCustomerDiscount implements DiscountStrategy { @Override public double calculateDiscount(double amount) { return amount * 0.15; // 15% rabatu } } public class VipCustomerDiscount implements DiscountStrategy { @Override public double calculateDiscount(double amount) { return amount * 0.25; // 25% rabatu } }
Teraz klasa Context która używa strategii:
public class ShoppingCart { private DiscountStrategy discountStrategy; public ShoppingCart(DiscountStrategy discountStrategy) { this.discountStrategy = discountStrategy; } public void setDiscountStrategy(DiscountStrategy discountStrategy) { this.discountStrategy = discountStrategy; } public double calculateTotal(double amount) { double discount = discountStrategy.calculateDiscount(amount); return amount - discount; } }
Użycie w praktyce
public class ECommerceDemo { public static void main(String[] args) { double orderAmount = 1000.0; // Zwykły klient ShoppingCart cart1 = new ShoppingCart(new RegularCustomerDiscount()); System.out.println("Regular customer pays: " + cart1.calculateTotal(orderAmount)); // Premium klient ShoppingCart cart2 = new ShoppingCart(new PremiumCustomerDiscount()); System.out.println("Premium customer pays: " + cart2.calculateTotal(orderAmount)); // Zmiana strategii w runtime cart1.setDiscountStrategy(new VipCustomerDiscount()); System.out.println("Now VIP price: " + cart1.calculateTotal(orderAmount)); } }
Kiedy używać Strategy pattern?
Strategy pattern świetnie sprawdza się gdy:
– Masz kilka sposobów wykonania tego samego zadania
– Chcesz uniknąć długich instrukcji if-else lub switch
– Algoritmy mogą się zmieniać w runtime
– Testujesz różne approaches i chcesz łatwo je wymieniać
Typowe błędy początkujących
Strategy vs inne wzorce
Wzorzec | Cel | Kiedy używać |
---|---|---|
Strategy | Wymienne algorytmy | Różne sposoby robienia tego samego |
State | Zmiana zachowania | Obiekt zmienia sposób działania |
Command | Enkapsulacja operacji | Kolejkowanie, logowanie operacji |
Nie znacząco. Overhead to jedno dodatkowe wywołanie metody, ale zyskujesz na czytelności i elastyczności kodu.
Gdy masz tylko jeden algorytm lub różnice są minimalne. Nie komplikuj kodu bez potrzeby.
Tak, w Javie 8 enum może implementować interfejsy i mieć metody. To dobra opcja dla prostych strategii.
Możesz użyć Factory pattern lub Map
Tak! Często używa się go z Factory (do tworzenia strategii) lub Decorator (do modyfikowania zachowania).
Przydatne zasoby:
🚀 Zadanie dla Ciebie
Zaimplementuj system płatności używając Strategy pattern. Stwórz strategie dla płatności kartą, PayPal i przelewy bankowe. Każda strategia powinna mieć różne opłaty za transakcję. Przetestuj zmienianie strategii w runtime.