0Pricing
PHP Academy · Lekcja

Wzorce behawioralne: Strategy, Observer, Command

Proszę modelować zachowanie i komunikację za pomocą wzorców behawioralnych.

Wzorce behawioralne: Strategy, Observer, Command to bezpłatna lekcja PHP Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej PHP Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs PHP Academy zawiera 4 lekcji w sumie.

Modelowanie zachowania

Wzorce behawioralne określają sposób współpracy obiektów i podziału odpowiedzialności. Skupimy się na trzech wzorcach, które stale pojawiają się w rzeczywistych systemach PHP:

  • Strategia — umożliwia wymianę algorytmu w czasie działania.
  • Obserwator — rozsyła zdarzenia do zainteresowanych odbiorców.
  • Polecenie — zamienia żądanie w obiekt, który można umieścić w kolejce, rejestrować lub cofnąć.

Strategia: idea

Wzorzec Strategia definiuje rodzinę wymiennych algorytmów za jednym interfejsem i pozwala klientowi wybrać algorytm w czasie działania. Zastępuje rozbudowaną instrukcję switch poniżej polimorfizmem: kontekst deleguje działanie strategii, którą przechowuje.

<?php
// The smell Strategy removes: branching on a type code
function price(string $type, float $base): float {
    switch ($type) {
        case 'standard': return $base + 5;
        case 'express':  return $base + 15;
        default: throw new InvalidArgumentException($type);
    }
}
echo price('express', 10), PHP_EOL; // 25

Strategia w kodzie

W tym przykładzie koszt wysyłki zależy od wybranego przewoźnika. Każda strategia enkapsuluje jeden algorytm wyceny, a kontekst pozostaje niezmieniony po dodaniu kolejnego przewoźnika.

<?php
interface ShippingStrategy { public function cost(float $weight): float; }
final class Standard implements ShippingStrategy {
    public function cost(float $w): float { return 5 + $w * 0.5; }
}
final class Express implements ShippingStrategy {
    public function cost(float $w): float { return 15 + $w * 1.2; }
}

final class Cart {
    public function __construct(private ShippingStrategy $strategy) {}
    public function setStrategy(ShippingStrategy $s): void { $this->strategy = $s; }
    public function quote(float $weight): float { return $this->strategy->cost($weight); }
}

$cart = new Cart(new Standard());
echo $cart->quote(10), PHP_EOL;     // 10
$cart->setStrategy(new Express());
echo $cart->quote(10), PHP_EOL;     // 27

Strategia z domknięciami

W PHP strategia nie zawsze musi być klasą. W prostych przypadkach element typu callable lub składnia callable pierwszej klasy jest w pełni poprawną strategią. Pełnych klas należy używać, gdy algorytm ma własny stan lub zależności, a domknięć — w przypadku prostych, bezstanowych wyborów.

<?php
$strategies = [
    'asc'  => fn(array $a) => sort($a) ? $a : $a,
    'desc' => fn(array $a) => rsort($a) ? $a : $a,
];
$data = [3, 1, 2];
print_r($strategies['desc']($data)); // [3,2,1]

Obserwator: idea

Wzorzec Obserwator pozwala, aby podmiot powiadamiał wielu obserwatorów o zmianie swojego stanu bez wiedzy o tym, kim oni są. Oddziela to źródło zdarzenia od jego obsługi i stanowi podstawę systemów zdarzeń, hooków oraz reaktywnych aktualizacji.

Obserwator w kodzie

Podmiot przechowuje listę obserwatorów i wywołuje update() dla każdego z nich. Nowi odbiorcy mogą się dołączać bez zmiany logiki podmiotu.

<?php
interface Observer { public function update(string $event): void; }

final class OrderSubject {
    private array $observers = [];
    public function subscribe(Observer $o): void { $this->observers[] = $o; }
    public function placed(string $id): void {
        foreach ($this->observers as $o) { $o->update("order $id placed"); }
    }
}
final class EmailObserver implements Observer {
    public function update(string $e): void { echo "email: $e" . PHP_EOL; }
}
final class AuditObserver implements Observer {
    public function update(string $e): void { echo "audit: $e" . PHP_EOL; }
}

$subject = new OrderSubject();
$subject->subscribe(new EmailObserver());
$subject->subscribe(new AuditObserver());
$subject->placed('42');

Obserwator a PSR-14

We współczesnym PHP wzorzec Obserwatora często wyraża się za pomocą dispatcherów zdarzeń PSR-14: dispatcher kieruje obiekt zdarzenia do zarejestrowanych odbiorców. Model pojęciowy pozostaje taki sam (podmiot = zdarzenie, obserwatorzy = odbiorcy), ale dispatcher dodatkowo je rozdziela i obsługuje zdarzenia, których propagację można zatrzymać. SplObserver/SplSubject istnieją w SPL, lecz obecnie są rzadko używane.

Polecenie: idea

Wzorzec Polecenie enkapsuluje żądanie w obiekcie: działanie, jego odbiorcę i parametry. Ponieważ żądanie staje się danymi, można je umieścić w kolejce, rejestrować, ponawiać lub cofać. Najprostsze polecenie po prostu przedstawia zamiar jako wartość, jak pokazano poniżej.

<?php
final class SendEmail {
    public function __construct(
        public readonly string $to,
        public readonly string $subject
    ) {}
}
// The request is now data you can store, serialize, or enqueue
$cmd = new SendEmail('user@example.com', 'Welcome');
echo json_encode($cmd), PHP_EOL;

Polecenie w kodzie

Każde polecenie implementuje execute(). Obiekt wywołujący przechowuje polecenia i uruchamia je niezależnie od ich działania. Dodanie undo() zmienia to rozwiązanie w pełny stos cofania.

<?php
interface Command { public function execute(): string; }

final class Light { public bool $on = false; }
final class TurnOn implements Command {
    public function __construct(private Light $light) {}
    public function execute(): string { $this->light->on = true; return 'light on'; }
}
final class TurnOff implements Command {
    public function __construct(private Light $light) {}
    public function execute(): string { $this->light->on = false; return 'light off'; }
}

final class Invoker {
    private array $queue = [];
    public function add(Command $c): void { $this->queue[] = $c; }
    public function run(): void {
        foreach ($this->queue as $c) { echo $c->execute(), PHP_EOL; }
    }
}

$light = new Light();
$inv = new Invoker();
$inv->add(new TurnOn($light));
$inv->add(new TurnOff($light));
$inv->run();

Szyny poleceń

Frameworki budują na tym wzorcu szynę poleceń: DTO polecenia jest przekazywane dokładnie jednemu obsługującemu. Middleware wokół szyny może w jednolity sposób dodawać transakcje, walidację i rejestrowanie. Ponieważ polecenia są zwykłymi obiektami możliwymi do serializacji, ten sam obsługujący może wykonywać je synchronicznie albo przekazywać do pracownika kolejki.

Wybór spośród wzorców

  • Strategia: jedna operacja i wiele wymiennych algorytmów wybieranych przez kod wywołujący.
  • Obserwator: jedno zdarzenie i wiele niezależnych reakcji, przy czym źródło nie zna odbiorców.
  • Polecenie: przedstawienie żądania jako obiektu, aby można je było umieścić w kolejce, rejestrować, ponawiać lub cofać.

Wzorce te dobrze się łączą: obsługujący polecenie może wybrać strategię i emitować zdarzenia dla obserwatorów.

Szybki test

Należy dopasować wymaganie do wzorca.

Podsumowanie

Modelowano zachowanie za pomocą trzech wzorców: Strategii do wymiany algorytmów w czasie działania (klas lub domknięć), Obserwatora do rozsyłania zmian stanu do niezależnych odbiorców (podstawa dispatcherów PSR-14) oraz Polecenia do zamiany żądań w obiekty, które można umieszczać w kolejce, rejestrować i cofać (podstawa szyn poleceń). Razem zapewniają elastyczną współpracę i przejrzysty podział odpowiedzialności.

Często zadawane pytania

Czy lekcja „Wzorce behawioralne: Strategy, Observer, Command” jest bezpłatna?

Tak — pełny tekst „Wzorce behawioralne: Strategy, Observer, Command” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu PHP Academy, przejdź na CoddyKit PRO. Kurs PHP Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wzorce behawioralne: Strategy, Observer, Command”?

Proszę modelować zachowanie i komunikację za pomocą wzorców behawioralnych. Ćwiczysz PHP Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć PHP Academy?

Nie wymagamy żadnego doświadczenia. PHP Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Wzorce behawioralne: Strategy, Observer, Command”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji PHP Academy?

Tak. Każda lekcja PHP Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Zasady SOLID w praktyce
  2. Wzorce kreacyjne: Factory, Builder, Singleton
  3. Wzorce strukturalne: Adapter, Decorator, Facade
  4. Wzorce behawioralne: Strategy, Observer, Command
← Powrót do PHP Academy