我正在尝试了解Memento模式。为此,我正在尝试实现撤消功能。问题是,每当我将发起者的旧状态保存在队列中并运行其他功能时,保存状态就会更改为当前状态。我真的需要帮助来了解我在做什么错。如何使向量不可变。

这是纪念品类。

package memento;

public class Memento
{
    private final boolean[] vectorState;

    public Memento(boolean[] vector) {vectorState = vector;}

    boolean[] getMemento() { return vectorState;}

}


发起者只需要向左移动布尔向量即可。
(TRUE,FALSE,FALSE)左移返回:(FALSE,FALSE,TRUE)。这是实现。

package memento;

public class ShilftLeftOriginator
{
    private boolean[] vector;

    public ShilftLeftOriginator(boolean[] vector) {this.vector = vector;}

    public void execute()
    {
        final boolean firstValue = this.vector[0];
        for (int i = 1; i < this.vector.length; i++) {
            this.vector[i - 1] = this.vector[i];
        }
        this.vector[vector.length - 1] = firstValue;
    }


    public Memento saveToMemento() {return new Memento(vector);}

}


和看守:

package memento;

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


public final class BooleanVector {
    private boolean[] vector;
    private Deque<Memento> mementoList = new LinkedList<>();

    public BooleanVector(boolean[] inputValues) {
        this.vector = inputValues;
    }


    @Override
    public boolean equals(Object obj)
    {
        if (obj == null) return false;
        if (!(obj instanceof BooleanVector)) return false;
        BooleanVector otherVector = (BooleanVector) obj;
        return Arrays.equals(this.vector, otherVector.vector);
    }

    public void shiftLeft()
    {
        ShilftLeftOriginator shiftLeft = new ShilftLeftOriginator(vector);
        mementoList.add(shiftLeft.saveToMemento());
        shiftLeft.execute(); // This is my Problem. After execute ist call the value(vector) in mementoList changes
    }

    public void undo(){ this.vector =  mementoList.pop().getMemento();}

}


现在是测试类和我收到的错误。

package memento;

public class Main {

    public static void main(String[] args) {
        boolean[] inputValues = { false, true, false };
        BooleanVector vector = new BooleanVector(inputValues);

        vector.shiftLeft();

        boolean[] expectedValues = new boolean[] { true, false, false };
        BooleanVector expectedVector = new BooleanVector(expectedValues);

        if (!vector.equals(expectedVector)) {
            throw new IllegalStateException(vector.toString());
        } else {
            System.out.println("shiftleft working");
        }

        vector.undo();

        expectedValues = new boolean[] { false, true, false };
        expectedVector = new BooleanVector(expectedValues);

        if (!vector.equals(expectedVector)) {
            throw new IllegalStateException(vector.toString());
        } else {
            System.out.println("undo working");
        }

    }

}


控制台输出:

shiftleft working
Exception in thread "main" java.lang.IllegalStateException: [true, false, false]
    at memento.Main.main(Main.java:26)

最佳答案

问题是您总是在操纵相同的数组。因此,如果您向左移动,您还将向左移动存储在Memento对象中的数组,因为它们都是相同的数组。

要解决此问题,请在Memento对象的构造函数中复制数组:

public Memento(boolean[] vector) {
    vectorState = Arrays.copyOf(vector, vector.length);
}


除此之外,您似乎混合了自己的课程。 BooleanVectorShilftLeftOriginator是发起者,而Main是看守者。

10-07 22:04