Wzorzec Strategia ma wiele podobieństw do wzorca metody wytwórczej. Różni się jednak miejscem i sposobem w którym go stosujemy.
Czym jest wzorzec kreacyjny?
Wzorce kreacyjne to grupa wzorców projektowych odpowiadających za sposób tworzenia obiektów w programie. Stosuje się je, gdy proces inicjalizacji obiektu jest złożony i wymaga oddzielenia od innych warstw aplikacji. Pozwalają one przenieść odpowiedzialność za tworzenie instancji do dedykowanych komponentów, dzięki czemu zmniejszają powiązania i umożliwiają elastyczne modyfikowanie sposobu powstawania obiektów.
Do najczęściej stosowanych wzorców kreacyjnych należą: Metoda Wytwórcza (Factory Method), Fabryka Abstrakcyjna (Abstract Factory), Singleton, Budowniczy (Builder), Prototyp (Prototype). Pozostałe wzorce postaram się opisać w kolejnych postach na blogu teraz skupię się na tych dwóch.
Porównanie
Wzorzec strategii pozwala na wybór algorytmu (zachowania) podczas działania programu. Umożliwia hermetyzację różnych algorytmów (strategii) i ich wymienność bez zmiany kodu klienta. Przykładowo oddziela się rodzinę algorytmów i definiuje wspólny interfejs, a konkretne strategie implementuje się w osobnych klasach, które można stosować zamiennie.
Metody kreacyjne (wytwórcze) są wzorcem zajmującym się tworzeniem obiektów – definiują interfejs do tworzenia obiektów, ale pozwalają podklasom decydować o tym, jaki konkretnie obiekt zostanie utworzony. To pozwala na rozluźnienie powiązania między kodem tworzącym obiekty a kodem, który je używa.
Podsumowując:
- Wzorzec strategii dotyczy wariantów zachowania/algorytmu.
- Metoda kreacyjna dotyczy sposobu tworzenia obiektów.
Przykład z obu wzorców w PHP:
// Wzorzec Strategii - różne metody sortowania
interface SortStrategy {
public function sort(array $data): array;
}
class QuickSort implements SortStrategy {
public function sort(array $data): array {
sort($data); // prosty sort dla przykładu
return $data;
}
}
class BubbleSort implements SortStrategy {
public function sort(array $data): array {
// implementacja sortowania bąbelkowego
$n = count($data);
for ($i = 0; $i < $n; $i++) {
for ($j = 0; $j < $n - 1; $j++) {
if ($data[$j] > $data[$j + 1]) {
$temp = $data[$j];
$data[$j] = $data[$j + 1];
$data[$j + 1] = $temp;
}
}
}
return $data;
}
}
class SortContext {
private SortStrategy $strategy;
public function __construct(SortStrategy $strategy) {
$this->strategy = $strategy;
}
public function setStrategy(SortStrategy $strategy) {
$this->strategy = $strategy;
}
public function sortData(array $data): array {
return $this->strategy->sort($data);
}
}
// Metoda Kreacyjna - fabryka tworząca strategie
abstract class StrategyFactory {
abstract public function createStrategy(): SortStrategy;
}
class QuickSortFactory extends StrategyFactory {
public function createStrategy(): SortStrategy {
return new QuickSort();
}
}
class BubbleSortFactory extends StrategyFactory {
public function createStrategy(): SortStrategy {
return new BubbleSort();
}
}
// Użycie
$factory = new QuickSortFactory();
$strategy = $factory->createStrategy();
$context = new SortContext($strategy);
$result = $context->sortData([5, 3, 9, 1]);
print_r($result);
Ten przykład pokazuje jak wzorzec strategii pozwala wybrać algorytm sortowania, a metoda kreacyjna (fabryka) decyduje, którą strategię tworzymy. Dzięki temu kod jest elastyczny i łatwo można zmienić zachowanie programu, tworząc nowe strategie i ich fabryki.
Takie połączenie wzorca strategii i metody kreacyjnej jest często spotykane w praktyce projektowej.
