溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

使用備忘錄模式實現(xiàn)Undo和Redo

發(fā)布時間:2020-08-19 07:25:08 來源:網(wǎng)絡(luò) 閱讀:320 作者:小熊跳舞 欄目:編程語言

備忘錄模式有三個角色。
1.發(fā)起人(Originator)角色:負責(zé)創(chuàng)建一個備忘錄,用以記錄當(dāng)前時刻自身的內(nèi)部狀態(tài),并可使用備忘錄恢復(fù)內(nèi)部狀態(tài)。實現(xiàn)其他業(yè)務(wù)功能。
2.備忘錄(Memento)角色:負責(zé)存儲發(fā)起人的內(nèi)部狀態(tài)。
3.管理者(Caretaker)角色:對備忘錄進行管理,提供保存與獲取備忘錄的功能,但其不能對備忘錄的內(nèi)容進行訪問與修改。

/**
 * 發(fā)起人角色
 *
 */
public class UnRedoOriginator {
    private String state;

    public UnRedoOriginator() {
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    public Memento createMemento() {
        return new Memento(state);
    }

    public void restoreMemento(Memento m) {
        if (m != null) {
            this.setState(m.getState());
        } else {
            System.out.println("沒有狀態(tài)可恢復(fù)");
        }
    }
}
/**
 * 備忘錄
 *
 */
public class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }
}
/**
 * 可undo和redo的備忘錄管理者
 *
 */
public class UnRedoCaretaker {
    /* 備忘列表 */
    private List<Memento> mementoList;
    /* 備忘列表容量,備忘列表容量 = 最大后退次數(shù) + 1 */
    private int capacity = 3;
    /* 后退索引 */
    private int undoIndex = -2;
    /* 前進索引 */
    private int redoIndex = 0;

    public UnRedoCaretaker() {
        this.mementoList = new LinkedList<>();
    }

    public UnRedoCaretaker(int capacity) {
        this();
        this.capacity = capacity;
    }

    /**
     * 添加備忘
     * 
     * @param memento
     */
    public void addMemento(Memento memento) {
        // 添加備忘前,移除當(dāng)前狀態(tài)之后的備忘
        for (int i = this.mementoList.size() - 1; i > this.undoIndex + 1; i--) {
            this.mementoList.remove(i);
        }

        if (this.mementoList.size() >= this.capacity) {
            this.mementoList.remove(0);
        }
        this.mementoList.add(memento);

        this.undoIndex = this.mementoList.size() - 2;
        this.redoIndex = this.mementoList.size();
    }

    /**
     * 后退操作
     * 
     * @return
     */
    public Memento undo() {
        Memento result = null;

        if (this.undoIndex >= 0 && this.undoIndex < this.mementoList.size() - 1) {
            result = this.mementoList.get(this.undoIndex);

            this.undoIndex--;
            this.redoIndex--;
        }

        return result;
    }

    /**
     * 前進操作
     * 
     * @return
     */
    public Memento redo() {
        Memento result = null;
        if (this.redoIndex > 0 && this.redoIndex < this.mementoList.size()) {
            result = this.mementoList.get(this.redoIndex);

            this.redoIndex++;
            this.undoIndex++;
        }

        return result;
    }
}

把發(fā)起人角色與備忘錄管理者角色聚合在一起,修改發(fā)起人角色類。

/**
 * 發(fā)起人角色
 *
 */
public class UnRedoOriginator {
    private String state;
    private UnRedoCaretaker caretaker;

    public UnRedoOriginator() {
        this.caretaker = new UnRedoCaretaker(3);
    }

    private void setState(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }

    private Memento createMemento() {
        return new Memento(state);
    }

    private void restoreMemento(Memento m) {
        if (m != null) {
            this.setState(m.getState());
        } else {
            System.out.println("沒有狀態(tài)可恢復(fù)");
        }
    }

    public void setAndStoreState(String state) {
        this.setState(state);
        caretaker.addMemento(this.createMemento());
    }

    public void undo() {
        this.restoreMemento(caretaker.undo());
    }

    public void redo() {
        this.restoreMemento(caretaker.redo());
    }
}

測試。

/**
 * 測試 undo和redo
 * 
 */
public class TestUnRedo {

    public static void main(String[] args) {
        UnRedoOriginator or = new UnRedoOriginator();

        /* 未設(shè)置狀態(tài)前進后退 */
        or.undo();
        or.redo();

        /* 連續(xù)添加操作 */
        System.out.println();
        int num = 1;
        operation(or, num++);
        operation(or, num++);
        operation(or, num++);
        operation(or, num++);

        /* 后退次數(shù)超過可后退次數(shù) */
        back(or);
        back(or);
        back(or);

        /* 后退時添加新操作,然后再后退 */
        System.out.println();
        operation(or, num++);
        back(or);
        forward(or);
        forward(or);// 前進次數(shù)超過可前進次數(shù)

        /* 后退時添加新操作,然后redo */
        System.out.println();
        back(or);
        operation(or, num++);
        forward(or);
    }

    private static void operation(UnRedoOriginator or, int name) {
        System.out.println("*******操作*******");
        or.setAndStoreState("操作" + name);
        System.out.println("當(dāng)前狀態(tài):" + or.getState());
    }

    private static void back(UnRedoOriginator or) {
        System.out.println("-------后退-------");
        or.undo();
        System.out.println("當(dāng)前狀態(tài):" + or.getState());
    }

    private static void forward(UnRedoOriginator or) {
        System.out.println("=======前進=======");
        or.redo();
        System.out.println("當(dāng)前狀態(tài):" + or.getState());
    }

}

運行結(jié)果如下。

沒有狀態(tài)可恢復(fù)
沒有狀態(tài)可恢復(fù)

*******操作*******
當(dāng)前狀態(tài):操作1
*******操作*******
當(dāng)前狀態(tài):操作2
*******操作*******
當(dāng)前狀態(tài):操作3
*******操作*******
當(dāng)前狀態(tài):操作4
-------后退-------
當(dāng)前狀態(tài):操作3
-------后退-------
當(dāng)前狀態(tài):操作2
-------后退-------
沒有狀態(tài)可恢復(fù)
當(dāng)前狀態(tài):操作2

*******操作*******
當(dāng)前狀態(tài):操作5
-------后退-------
當(dāng)前狀態(tài):操作2
=======前進=======
當(dāng)前狀態(tài):操作5
=======前進=======
沒有狀態(tài)可恢復(fù)
當(dāng)前狀態(tài):操作5

-------后退-------
當(dāng)前狀態(tài):操作2
*******操作*******
當(dāng)前狀態(tài):操作6
=======前進=======
沒有狀態(tài)可恢復(fù)
當(dāng)前狀態(tài):操作6
向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI