Summer SALE
Polecenie

Polecenie w języku C++

Polecenie to behawioralny wzorzec projektowy według którego żądania lub proste działania są konwertowane na obiekty.

Wyżej wymieniona konwersja pozwala odkładać zadania w czasie, uruchamiać je zdalnie, przechowywać ich historię, itp.

Złożoność:

Popularność:

Przykłady użycia: Wzorzec Polecenie jest dość powszechny w kodzie napisanym w C++ jako alternatywa dla wywołania zwrotnego (ang. callback) zakładającego przypisanie akcji elementom interfejsu użytkownika. Jest stosowany także w celu kolejkowania zadań, śledzenia historii wykonanych działań, itp.

Identyfikacja: Jeśli widzisz zestaw powiązanych klas odpowiadających konkretnym czynnościom (jak “Kopiuj”, “Wytnij”, “Wyślij”, “Drukuj”, itd.) — może to oznaczać użycie wzorca Polecenie. Takie klasy powinny implementować ten sam interfejs/klasę abstrakcyjną. Polecenia mogą samodzielnie implementować poszczególne czynności lub delegować zadania osobnym obiektom — zwanym odbiorcami. Ostatnim elementem układanki jest znalezienie obiektu wywołującego — będzie to klasa przyjmująca obiekty-polecenia w charakterze parametrów swoich metod lub konstruktora.

Przykład koncepcyjny

Poniższy przykład ilustruje strukturę wzorca Polecenie ze szczególnym naciskiem na następujące kwestie:

  • Z jakich składa się klas?
  • Jakie role pełnią te klasy?
  • W jaki sposób elementy wzorca są ze sobą powiązane?

main.cc: Przykład koncepcyjny

/** * The Command interface declares a method for executing a command. */ class Command { public: virtual ~Command() { } virtual void Execute() const = 0; }; /** * Some commands can implement simple operations on their own. */ class SimpleCommand : public Command { private: std::string pay_load_; public: explicit SimpleCommand(std::string pay_load) : pay_load_(pay_load) { } void Execute() const override { std::cout << "SimpleCommand: See, I can do simple things like printing (" << this->pay_load_ << ")\n"; } }; /** * The Receiver classes contain some important business logic. They know how to * perform all kinds of operations, associated with carrying out a request. In * fact, any class may serve as a Receiver. */ class Receiver { public: void DoSomething(const std::string &a) { std::cout << "Receiver: Working on (" << a << ".)\n"; } void DoSomethingElse(const std::string &b) { std::cout << "Receiver: Also working on (" << b << ".)\n"; } }; /** * However, some commands can delegate more complex operations to other objects, * called "receivers." */ class ComplexCommand : public Command { /** * @var Receiver */ private: Receiver *receiver_; /** * Context data, required for launching the receiver's methods. */ std::string a_; std::string b_; /** * Complex commands can accept one or several receiver objects along with any * context data via the constructor. */ public: ComplexCommand(Receiver *receiver, std::string a, std::string b) : receiver_(receiver), a_(a), b_(b) { } /** * Commands can delegate to any methods of a receiver. */ void Execute() const override { std::cout << "ComplexCommand: Complex stuff should be done by a receiver object.\n"; this->receiver_->DoSomething(this->a_); this->receiver_->DoSomethingElse(this->b_); } }; /** * The Invoker is associated with one or several commands. It sends a request to * the command. */ class Invoker { /** * @var Command */ private: Command *on_start_; /** * @var Command */ Command *on_finish_; /** * Initialize commands. */ public: ~Invoker() { delete on_start_; delete on_finish_; } void SetOnStart(Command *command) { this->on_start_ = command; } void SetOnFinish(Command *command) { this->on_finish_ = command; } /** * The Invoker does not depend on concrete command or receiver classes. The * Invoker passes a request to a receiver indirectly, by executing a command. */ void DoSomethingImportant() { std::cout << "Invoker: Does anybody want something done before I begin?\n"; if (this->on_start_) { this->on_start_->Execute(); } std::cout << "Invoker: ...doing something really important...\n"; std::cout << "Invoker: Does anybody want something done after I finish?\n"; if (this->on_finish_) { this->on_finish_->Execute(); } } }; /** * The client code can parameterize an invoker with any commands. */ int main() { Invoker *invoker = new Invoker; invoker->SetOnStart(new SimpleCommand("Say Hi!")); Receiver *receiver = new Receiver; invoker->SetOnFinish(new ComplexCommand(receiver, "Send email", "Save report")); invoker->DoSomethingImportant(); delete invoker; delete receiver; return 0; } 

Output.txt: Wynik działania

Invoker: Does anybody want something done before I begin? SimpleCommand: See, I can do simple things like printing (Say Hi!) Invoker: ...doing something really important... Invoker: Does anybody want something done after I finish? ComplexCommand: Complex stuff should be done by a receiver object. Receiver: Working on (Send email.) Receiver: Also working on (Save report.) 

Polecenie w innych językach

Polecenie w języku C# Polecenie w języku Go Polecenie w języku Java Polecenie w języku PHP Polecenie w języku Python Polecenie w języku Ruby Polecenie w języku Rust Polecenie w języku Swift Polecenie w języku TypeScript