Java Academy · Lektion

Command-mønsteret: indkapsling af handlinger

Indpak forespørgsler som Command-objekter for at understøtte fortryd/gentag og makrooptagelse.

Lektion 3 af 414 trin

Command-mønsteret: indkapsling af handlinger er en gratis Java Academy-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Java Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Java Academy-kurset indeholder 4 lektioner i alt.

Kommandoens formål

Kommandomønstret indkapsler en anmodning som et objekt, så klienter kan parametriseres med forskellige anmodninger, og så anmodninger kan sættes i kø, logføres og fortrydes.

Kommandoens grænseflade

Definér en grænseflade med en execute()-metode og eventuelt en undo()-metode. Hvert kommandoobjekt ved, hvordan én handling udføres og omgøres.

public interface Command {
    void execute();
    void undo();
}

Konkret kommando: TextEditor

Hver konkret kommando indkapsler en modtager og handlingens parametre. Udførelse foretager handlingen, mens fortrydelse omgør den.

public class InsertTextCommand implements Command {
    private final TextEditor editor;
    private final String text;
    private final int position;
    public InsertTextCommand(TextEditor editor, String text, int pos) {
        this.editor = editor; this.text = text; this.position = pos;
    }
    public void execute() { editor.insert(position, text); }
    public void undo()    { editor.delete(position, text.length()); }
}

Kaldende objekt: CommandHistory

Det kaldende objekt gemmer en historik over udførte kommandoer. Det kalder execute() og lægger kommandoen på en stak. Fortrydelse tager den øverste kommando af stakken og kalder undo().

public class CommandHistory {
    private final Deque<Command> history = new ArrayDeque<>();
    public void execute(Command cmd) {
        cmd.execute();
        history.push(cmd);
    }
    public void undo() {
        if (!history.isEmpty()) history.pop().undo();
    }
}

Fortrydelses-/gentagelsesstak

Tilføj en gentagelsesstak: Når du fortryder, lægger du kommandoen på gentagelsesstakken. Når du gentager, tager du den øverste kommando af gentagelsesstakken og udfører den igen.

private final Deque<Command> undoStack = new ArrayDeque<>();
private final Deque<Command> redoStack = new ArrayDeque<>();
public void redo() {
    if (!redoStack.isEmpty()) {
        Command cmd = redoStack.pop();
        cmd.execute();
        undoStack.push(cmd);
    }
}

Makrokommando

En makrokommando er en sammensat kommando, der indeholder en liste over kommandoer og udfører dem i rækkefølge. Fortrydelse udfører de omvendte handlinger i omvendt rækkefølge.

public class MacroCommand implements Command {
    private final List<Command> commands;
    public MacroCommand(List<Command> commands) { this.commands = commands; }
    public void execute() { commands.forEach(Command::execute); }
    public void undo()    { for (int i = commands.size()-1; i>=0; i--) commands.get(i).undo(); }
}

Kommandokø til behandling af opgaver

Gem kommandoer i en kø, og behandl dem asynkront. En arbejdertråd tager kommandoer fra køen og udfører dem, så producenterne afkobles fra udførelsestråden.

BlockingQueue<Command> queue = new LinkedBlockingQueue<>();
// Producer:
queue.put(new SendEmailCommand(recipient, subject, body));
// Consumer thread:
Command cmd = queue.take();
cmd.execute();

Kommando med Executor

Pak kommandoer ind som Runnable-lambdaer, og send dem til en ExecutorService – lambdaen er kommandoobjektet.

ExecutorService exec = Executors.newFixedThreadPool(4);
exec.submit(() -> sendEmail(recipient, subject));
exec.submit(() -> generateReport(params));

Logning af kommandoer til revision

Serialiserbare kommandoobjekter kan gemmes i en log. Ved gendannelse afspiller du dem for at rekonstruere den endelige tilstand – grundlaget for hændelsesbaseret lagring.

void execute(Command cmd) {
    cmd.execute();
    auditLog.append(cmd.toString()); // log every action
    history.push(cmd);
}

Handlingsknapper i grafiske brugerflader

I rammeværk til grafiske brugerflader indeholder hver knap eller hvert menupunkt en kommando. Når du klikker på knappen, kaldes command.execute(). Udskift kommandoer under kørsel for at ændre knappens funktion.

Button saveBtn = new Button("Save");
saveBtn.setOnAction(() -> new SaveDocumentCommand(doc).execute());

Kommando kontra strategi

Begge indkapsler adfærd. Strategimønstret indkapsler en algoritme, der kan udskiftes under kørsel. Kommandomønstret indkapsler en komplet anmodning inklusive dens parametre og modtager og understøtter historik og køer.

Kommando i Spring

Tasklet i Spring Batch og MessageHandler i Spring Integration er kommandomønstre på applikationsniveau. Hver Tasklet indkapsler ét trin i et batchjob.

Hurtigt tjek

Hvilken ekstra metode tilføjer kommandomønstret ud over execute() for at understøtte fortrydelse?

Opsummering

Kommandomønstret indkapsler handlinger som objekter. Brug det til fortrydelses-/gentagelsesstakke, opgavekøer, makrooptagelse og revisionslogning. Kombinér det med et kaldende objekt, der vedligeholder kommandohistorikken.

Gratis at komme i gang

Lær Java med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
104
Lektioner
374

Ofte stillede spørgsmål

Er lektionen “Command-mønsteret: indkapsling af handlinger” gratis?

Ja — hele teksten til “Command-mønsteret: indkapsling af handlinger” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Java Academy-kurset, skal du opgradere til CoddyKit PRO. Java Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Command-mønsteret: indkapsling af handlinger”?

Indpak forespørgsler som Command-objekter for at understøtte fortryd/gentag og makrooptagelse. Du øver dig i Java Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Java Academy?

Der kræves ingen tidligere erfaring. Java Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Command-mønsteret: indkapsling af handlinger”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Java Academy-lektion?

Ja. Alle Java Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Observer-mønsteret: hændelsesnotifikation
  2. Strategy-mønsteret: udskiftelige algoritmer
  3. Command-mønsteret: indkapsling af handlinger
  4. Template Method: definition af algoritmeskeletter
← Tilbage til Java Academy