Menu
Coddy logo textTech

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 OFF

Wzorzec 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.

challenge icon

Wyzwanie

Łatwy

Zbudujmy 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 interfejs Command z 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 interfejs Command:
    • WriteCommand: Przyjmuje w konstruktorze obiekt TextEditor oraz ciąg tekstowy. Jego metoda execute() wywołuje metodę write() edytora i zwraca wynik.
    • ClearCommand: Przyjmuje w konstruktorze obiekt TextEditor. Jego metoda execute() 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ła execute() polecenia i wyświetli wynik.

    W nowym wierszu wyświetl aktualną treść edytora w tym formacie: Content: [content] (jeśli jest pusta, wyświetl tylko Content: 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)

?>
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator PHP online