命令模式-Command(Java實現)


命令模式-Command

將一個命令請求封裝為一個對象, 這樣就可以使用命令來修改目標對象的相關參數了.

本文的例子是, 狗主人(Master) 希望對狗狗發一些命令, 狗來進行響應, 以達到修改"參數"的作用.

比如, 發出讓狗狗坐下, 吐舌頭 等命令后...狗狗的參數就從站着變為了坐着, 從沒伸出舌頭變為了吐出舌頭.

HandState枚舉

public enum HandState {
    REACH("伸出爪子"), BACK("沒伸出爪子");

    private String handState;

    HandState(String handState) {
        this.handState = handState;
    }

    @Override
    public String toString() {
        return handState;
    }
}

PostureState枚舉

public enum PostureState {
    SITTING("坐着"), STANDING("站着");

    private String posture;

    PostureState(String posture) {
        this.posture = posture;
    }

    @Override
    public String toString() {
        return posture;
    }
}

TongueState枚舉

public enum TongueState {
    SPIT("吐出舌頭"), BACK("沒伸出舌頭");

    private String tongueState;

    TongueState(String tongueState) {
        this.tongueState = tongueState;
    }

    @Override
    public String toString() {
        return tongueState;
    }
}

Command接口

命令的抽象定義.

public interface Command {

    /**
     * 對dog執行命令
     */
    void execute(Dog dog);

    /**
     * 再來一遍剛剛那次execute(dog)
     */
    void undo();

    /**
     * 撤銷剛剛那次execute(dog)
     */
    void redo();

    @Override
    String toString();

}

HandStateCommand類

握手命令

public class HandStateCommand implements Command {

    private Dog dog;

    @Override
    public void execute(Dog dog) {
        dog.setHandState(HandState.REACH);
        this.dog = dog;
    }

    @Override
    public void undo() {
        if (dog != null) {
            dog.setHandState(HandState.BACK);
        }
    }

    @Override
    public void redo() {
        if (dog != null) {
            dog.setHandState(HandState.REACH);
        }
    }

    @Override
    public String toString() {
        return "讓狗伸出爪子的命令";
    }
}

PostureStateCommand類

站立/坐下姿勢命令.

public class PostureStateCommand implements Command {

    private Dog dog;

    @Override
    public void execute(Dog dog) {
        dog.setPostureState(PostureState.SITTING);
        this.dog = dog;
    }

    @Override
    public void undo() {
        if (dog != null) {
            dog.setPostureState(PostureState.STANDING);
        }
    }

    @Override
    public void redo() {
        if (dog != null) {
            dog.setPostureState(PostureState.SITTING);
        }
    }

    @Override
    public String toString() {
        return "讓狗坐下的命令";
    }
}

TongueStateCommand類

伸舌頭/合上嘴 命令

public class TongueStateCommand implements Command {

    private Dog dog;

    @Override
    public void execute(Dog dog) {
        dog.setTongueState(TongueState.SPIT);
        this.dog = dog;
    }

    @Override
    public void undo() {
        if (dog != null) {
            dog.setTongueState(TongueState.BACK);
        }
    }

    @Override
    public void redo() {
        if (dog != null) {
            dog.setTongueState(TongueState.SPIT);
        }
    }

    @Override
    public String toString() {
        return "讓狗吐出舌頭的命令";
    }
}

Dog類

被命令的對象, 根據命令會改變Dog類的狀態.

public class Dog {
    private HandState handState;
    private PostureState postureState;
    private TongueState tongueState;

    {
        handState = HandState.BACK;
        postureState = PostureState.STANDING;
        tongueState = TongueState.BACK;
    }

    public void setHandState(HandState handState) {
        this.handState = handState;
    }

    public void setPostureState(PostureState postureState) {
        this.postureState = postureState;
    }

    public void setTongueState(TongueState tongueState) {
        this.tongueState = tongueState;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "handState=" + handState +
                ", postureState=" + postureState +
                ", tongueState=" + tongueState +
                '}';
    }

    public void printStatus() {
        System.out.println(this);
    }
}

Master類

由Master來施加命令來對Dog進行一些參數上的改變.

import java.util.Deque;
import java.util.LinkedList;

public class Master {

    private Deque<Command> undoStack = new LinkedList<>();
    private Command redo ;

    public Master() {
    }

    public void sendCommand(Command command, Dog dog) {
        System.out.printf("主人使用命令:<%s>\n", command);
        command.execute(dog);
        redo = command;
        undoStack.offerLast(command);
    }

    public void undoLastCommand() {
        if (!undoStack.isEmpty()) {
            Command previousSpell = undoStack.pollLast();
            redo = previousSpell;
            System.out.printf("主人撤回命令:<%s>\n", previousSpell);
            previousSpell.undo();
        }
    }

    public void redoLastCommand() {
        if (redo!=null) {
            undoStack.offerLast(redo);
            System.out.printf("再一次執行了命令:<%s>\n", redo);
            redo.redo();
        }
    }

    @Override
    public String toString() {
        return "狗的主人";
    }
}

Main

運行程序/ 場景模擬

public class Main {
    public static void main(String[] args) {
        Master master = new Master();

        Dog dog = new Dog();
        dog.printStatus();

        //開始命令狗, 站姿坐姿
        master.sendCommand(new PostureStateCommand(), dog);
        dog.printStatus();

        // 開始命令狗, 吐舌頭
        master.sendCommand(new TongueStateCommand(), dog);
        dog.printStatus();

        master.redoLastCommand();
        dog.printStatus();

        master.undoLastCommand();
        dog.printStatus();

        master.redoLastCommand();
        dog.printStatus();

        master.undoLastCommand();
        dog.printStatus();

        // 開始命令狗, 伸爪子
        master.sendCommand(new HandStateCommand(), dog);
        dog.printStatus();

        master.redoLastCommand();
        dog.printStatus();

        master.undoLastCommand();
        dog.printStatus();
    }
}

運行結果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM