Sobes.tech
Middle+

Používate vo svojej práci vzorec Command?

sobes.tech AI

Odpoveď od AI

Áno, vo svojej práci používam vzor Command.

Vzor Command (Príkaz) zapuzdruje požiadavku vo forme objektu, čím umožňuje parameterizovať klientov s rôznymi požiadavkami, zaradiť požiadavky do fronty alebo ich zaznamenať, podporovať zrušenie operácií.

Používam ho, keď:

  • je potrebné parameterizovať objekty vykonávanou akciou.
  • je potrebné zaradiť operácie do fronty, naplánovať ich vykonanie alebo zaznamenať.
  • je potrebné implementovať mechanizmus zrušenia (undo) alebo opakovania (redo) operácií.
  • nízkoúrovňové operácie musia byť prispôsobené pre vysokoúrovňové komponenty.

Príklady použitia:

  • systémy s grafickým rozhraním, kde príkazy zodpovedajú akciám používateľa (napríklad "Vložiť", "Kopírovať").
  • systémy riadenia transakcií.
  • distribuované systémy a fronty správ.
  • implementácia makier alebo skriptov.

Štrukturálne vzor obsahuje:

  • Command: rozhranie alebo abstraktná trieda, ktorá vyhlasuje metódu na vykonanie operácie.
  • ConcreteCommand: konkrétna implementácia Command, ktorá spája príjemcu s akciou. Obsahuje odkaz na Receiver.
  • Client: vytvára objekt ConcreteCommand a nastavuje príjemcu.
  • Invoker: volá vykonanie príkazu. Uchováva objekt Command.
  • Receiver: objekt, ktorý vykonáva samotnú akciu.

Príklad: Jednoduchá implementácia príkazu na prepínanie svetla.

// Rozhranie príkazu
interface Command {
    void execute();
    void undo(); // Na podporu zrušenia
}

// Prijímateľ
class Light {
    private boolean isOn = false;

    public void turnOn() {
        isOn = true;
        System.out.println("Svetlo je ZAPNUTÉ");
    }

    public void turnOff() {
        isOn = false;
        System.out.println("Svetlo je VYPNUTÉ");
    }
}

// Konkrétny príkaz na zapnutie svetla
class TurnOnLightCommand implements Command {
    private Light light;

    public TurnOnLightCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.turnOn();
    }

    @Override
    public void undo() {
        light.turnOff(); // Na zrušenie zapnutia
    }
}

// Konkrétny príkaz na vypnutie svetla
class TurnOffLightCommand implements Command {
    private Light light;

    public TurnOffLightCommand(Light light) {
        this.light = light;
    }

    @Override
    public void execute() {
        light.turnOff();
    }

    @Override
    public void undo() {
        light.turnOn(); // Na zrušenie vypnutia
    }
}

// Volajúci (Invoker)
class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        command.execute();
    }

    public void pressUndoButton() {
        command.undo(); // Na zrušenie
    }
}

// Klient
public class Client {
    public static void main(String[] args) {
        Light livingRoomLight = new Light(); // Prijímateľ

        Command turnOn = new TurnOnLightCommand(livingRoomLight); // Konkrétny príkaz
        Command turnOff = new TurnOffLightCommand(livingRoomLight);

        RemoteControl remote = new RemoteControl(); // Volajúci

        remote.setCommand(turnOn);
        remote.pressButton(); // Svetlo je ZAPNUTÉ

        remote.pressUndoButton(); // Svetlo je VYPNUTÉ

        remote.setCommand(turnOff);
        remote.pressButton(); // Svetlo je VYPNUTÉ

        remote.pressUndoButton(); // Svetlo je ZAPNUTÉ
    }
}

Porovnávacia tabuľka s inými vzormi:

Vzor Hlavný účel Rozdiel od Command
Strategy Definuje rodinu algoritmov a zapuzdruje každý z nich. Zapuzdruje celý algoritmus (čo robiť), zatiaľ čo Command je konkrétna akcia (ako to urobiť).
Observer Definuje závislosť "jeden ku mnohým" medzi objektmi. Vzťahuje sa na oznámenia o zmenách stavu, nie na vykonávanie požiadaviek.
Memento Uloženie a obnovenie stavu objektu bez narušenia zapuzdrenia. Používa sa na uloženie stavu, nie na zapuzdrenie akcií.