Porównanie: Wzorzec Strategia a metoda wytwórcza.


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.