Wzorzec polecenia
Część sekcji Programowanie obiektowe ścieżki PHP w Coddy. Lekcja 75 z 91.
Wzorzec polecenia to behawioralny wzorzec projektowy, który przekształca żądanie w samodzielny obiekt zawierający wszystkie informacje o żądaniu. Dzięki tej transformacji możesz przekazywać żądania jako argumenty metod, opóźniać ich wykonanie lub umieszczać je w kolejce, a także obsługiwać operacje, które można cofnąć.
Pomyśl o restauracji.
Gdy zamawiasz jedzenie, kelner zapisuje zamówienie na kartce (poleceniu), zanosi je do kuchni, a kucharz je realizuje. Kelner nie musi wiedzieć, jak gotować; po prostu przekazuje polecenie.
To oddziela zlecającego od wykonawcy.
Oto podstawowa implementacja:
<?php
interface Command {
public function execute(): string;
}class Light {
public function on(): string { return "Light is ON"; }
public function off(): string { return "Light is OFF"; }
}class LightOnCommand implements Command {
public function __construct(private Light $light) {}
public function execute(): string {
return $this->light->on();
}
}class LightOffCommand implements Command {
public function __construct(private Light $light) {}
public function execute(): string {
return $this->light->off();
}
}
Wywołujący uruchamia polecenia, nie wiedząc, co robią:
<?php
class RemoteControl {
public function press(Command $command): string {
return $command->execute();
}
}$light = new Light();
$remote = new RemoteControl();
echo $remote->press(new LightOnCommand($light)) . "\n";
echo $remote->press(new LightOffCommand($light));
Wynik:
Light is ON
Light is OFFWzorzec Polecenia sprawdza się doskonale, gdy potrzebujesz kolejkować operacje, zaimplementować funkcję cofania lub rejestrować działania. Każde polecenie jest samodzielne, co ułatwia dodawanie nowych poleceń bez modyfikowania istniejącego kodu.
Wyzwanie
ŁatwyZbudujmy system poleceń edytora tekstu z użyciem wzorca Polecenie. Edytory tekstu często muszą obsługiwać operacje takie jak wpisywanie tekstu, usuwanie tekstu i cofanie działań: każda operacja staje się samodzielnym obiektem polecenia, który można wykonać za pomocą ujednoliconego interfejsu.
Rozmieścisz swój kod w czterech plikach:
Command.php: Zdefiniuj interfejsCommandz jedną metodąexecute(): string. Określa on kontrakt, którego muszą przestrzegać wszystkie polecenia edytora.TextEditor.php, Utwórz klasęTextEditor, która reprezentuje odbiorcę — obiekt faktycznie wykonujący pracę. Edytor powinien:- Przechowywać aktualną treść tekstu (zacznij od pustego ciągu znaków)
- Mieć metodę
write(string $text): string, która dopisuje tekst do treści i zwraca"Written: [text]" - Mieć metodę
clear(): string, która usuwa treść i zwraca"Content cleared" - Mieć metodę
getContent(): string, która zwraca aktualną treść
Commands.php: Dołącz pliki Command i TextEditor. Utwórz dwie klasy poleceń implementujące interfejsCommand:WriteCommand: Przyjmuje w konstruktorze obiektTextEditororaz ciąg tekstowy. Jego metodaexecute()wywołuje metodęwrite()edytora i zwraca wynik.ClearCommand: Przyjmuje w konstruktorze obiektTextEditor. Jego metodaexecute()wywołuje metodęclear()edytora i zwraca wynik.
main.php: Dołącz plik Commands. Otrzymasz dwa dane wejściowe: typ polecenia ("write"lub"clear") oraz ciąg tekstowy (używany tylko w przypadku poleceń zapisu).Utwórz instancję
TextEditor. Na podstawie typu polecenia utwórz odpowiedni obiekt polecenia. Następnie utwórz funkcję wywołującą lub prosty mechanizm, który wywołaexecute()polecenia i wyświetli wynik.W nowym wierszu wyświetl aktualną treść edytora w tym formacie:
Content: [content](jeśli jest pusta, wyświetl tylkoContent:bez żadnego tekstu po spacji).
To wyzwanie pokazuje, jak wzorzec Polecenie hermetyzuje każdą operację w postaci obiektu. Wywołujący nie musi wiedzieć, czy wykonuje polecenie zapisu, czy czyszczenia. Po prostu wywołuje execute() i pozostawia szczegóły poleceniu.
Spróbuj swoich sił
<?php
require_once 'Commands.php';
// Odczytaj dane wejściowe
$commandType = trim(fgets(STDIN)); // "write" lub "clear"
$text = trim(fgets(STDIN)); // tekst dla polecenia write
// TODO: Utwórz instancję TextEditor
// TODO: Na podstawie typu polecenia utwórz odpowiedni obiekt polecenia
// - Jeśli "write", utwórz WriteCommand z edytorem i tekstem
// - Jeśli "clear", utwórz ClearCommand z edytorem
// TODO: Utwórz mechanizm wywołujący execute() na obiekcie polecenia
// i wypisujący wynik
// TODO: Wypisz bieżącą zawartość edytora w formacie: "Content: [content]"
// (jeśli jest pusta, wypisz tylko "Content: " bez niczego po spacji)
?>Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrzneWprowadzenie do programowania obiektowegoKlasy a obiektySłowo kluczowe $thisMetodyWłaściwościKonstruktor (__construct)Destruktor (__destruct)Powtórka — prosty kalkulator4Dziedziczenie
Podstawy dziedziczeniaSłowo kluczowe parent::Przesłanianie metodSłowo kluczowe finalKlasy abstrakcyjnePowtórzenie – hierarchia pracowników7Enkapsulacja
Public, protected, privateModyfikatory dostępu w szczegółachGettery i setteryUkrywanie informacjiPromocja parametrów konstruktora (8.0)Podsumowanie — system ewidencji studentów10Zaawansowane koncepcje OOP
Kompozycja a dziedziczenieWstrzykiwanie zależnościKlasy anonimoweEnumy (PHP 8.1)Włókna (PHP 8.1)Dogłębne omówienie klonowania obiektówGeneratory i iteratory13Wzorce projektowe, część 2
Wzorzec poleceniaWzorzec adapteraWzorzec dekoratoraWzorzec metody szablonowejWzorzec stanuWzorzec kompozytuWzorzec repozytorium2Przestrzenie nazw i autoloading
Wprowadzenie do przestrzeni nazwSłowo kluczowe useStandard autoloadingu PSR-4Autoloader ComposeraPodsumowanie – uporządkowany projekt5Interfejsy i kontrakty
Wprowadzenie do interfejsówImplementowanie interfejsówImplementowanie wielu interfejsówInterfejs a klasa abstrakcyjnaPodpowiadanie typów za pomocą interfejsówPodsumowanie — kalkulator kształtów8Metody magiczne
Wprowadzenie do metod magicznych__toString i __debugInfo__get, __set, __isset, __unset__call i __callStatic__clone i klonowanie obiektów__serialize i __unserializePodsumowanie — własna kolekcja11System typów i obsługa błędów
Deklaracje typówTypy nullableTypy sumy i przecięciaKlasy wyjątkówNiestandardowa hierarchia wyjątkówTry, Catch, FinallyPodsumowanie — walidator formularzy14Projekt: Zarządzanie biblioteką
Przegląd projektuKlasy książki i użytkownika3Właściwości klas
Właściwości instancji a właściwości statyczneStałe w klasachMetody i właściwości statyczneWłaściwości prywatne i chronioneWłaściwości tylko do odczytu (PHP 8.1)Podsumowanie — menedżer kont bankowych6Polimorfizm
Ponowne omówienie nadpisywania metodPolimorfizm za pomocą interfejsówPodpowiedzi typów i typy sumyPóźne wiązanie statycznePodsumowanie — procesor płatności9Cechy
Wprowadzenie do cechKorzystanie z wielu cechRozwiązywanie konfliktów cechMetody abstrakcyjne w cechachCechy a dziedziczenie12Wzorce projektowe, część 1
Wprowadzenie do wzorców projektowychWzorzec SingletonWzorzec FactoryWzorzec ObserverWzorzec StrategyPoćwicz samodzielnie: Kompilator PHP online