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
- Zasady SOLID w praktyce
- Wzorce kreacyjne: Factory, Builder, Singleton
- Wzorce strukturalne: Adapter, Decorator, Facade
- Wzorce behawioralne: Strategy, Observer, Command