Memento не обновляет состояние с отменой в Java

У меня есть graph, который содержит vertices и edges, и у меня есть класс originator, который содержит graph, который следует использовать для insert vertices или get the list of vertices в graph.

интерфейс vertex

public interface Vertex<V> {
    public V element();
}

интерфейс edge

public interface Edge<E, V> {
    public E element();
    public Vertex<V>[] vertices();
}

интерфейс graph с вставкой новой вершины и другим методом hide()

public interface Graph<V, E> {
  public void insertVertex(V vElement);
  public Iterable<Vertex<V>> vertices();
}

Реализация ADT Graph, в которой хранится коллекция vertices (и ребер, но не обязательно)

public class GraphEdgeList<V, E> implements Graph<V, E> {
    private Map<V, Vertex<V>> vertices;

    public GraphEdgeList() {
        this.vertices = new HashMap<>();
    }

    @Override
    public void insertVertex(V vElement) {
     //method to insert new vertex element
     //not need to return nothing
    }

    @Override
    public Iterable<Vertex<V>> vertices() {
    //return a list of vertices in graph
    }
}

класс Memento

public class Memento {
    private Graph graph;

    public Memento(Originator originator) {
        graph = originator.getGraph();
    }

    public Graph getGraph() {
        return graph;
    }
}

класс Originator

public class Originator<V,E> {
    private Graph<V,E> graph;
    private Caretaker caretaker;

    public Originator(Caretaker caretaker) {
      this.graph = new GraphEdgeList();
      this.caretaker = caretaker;
    }

    public Memento createMemento() {//create new memento
        return new Memento(this);
    }

    public void setMemento(Memento memento) {//set memento
       graph = memento.getGraph();
    }

    public Graph getGraph() {
      return graph;
    }

    public Caretaker getCaretaker() {
     return caretaker;
    }
}

Интерфейс IMemento

public interface IMemento {
    public void save(Originator originator);
    public void restore(Originator originator);
}

класс CareTaker реализует интерфейс IMemento

public class Caretaker implements IMemento {

    private final Stack<Memento> undoMemento;//stack explicit

    public Caretaker() {
        this.undoMemento = new StackDynamic();
    }

    @Override
    public void save(Originator originator) {
        Memento memento = originator.createMemento();
        undoMemento.push(memento);
    }

    @Override
    public void restore(Originator originator) {
        if (undoMemento.isEmpty() != true) {
            Memento memento = undoMemento.pop();
            originator.setMemento(memento);
       }
    }
}

мои сомнения начинаются после сохранения состояния, и при попытке выполнить отмену graph не обновляется до предыдущего состояния

public class Main {
    public static void main(String[] args) {
        Caretaker caretaker = new Caretaker();
        Originator<String, String> originator = new Originator(caretaker);

        //create new string and insert in graph
        originator.getGraph.insertVertex("A");
        //caretaker save state
        caretaker.save(originator);

       //create another string and insert in graph
        originator.getGraph.insertVertex("B");
        //caretaker save state
        caretaker.save(originator);      
    }
}

но когда я восстанавливаю de graph все еще с 2 вершинами

caretaker.restore(originator);

любое предложение?


person Renata P Souza    schedule 04.02.2019    source источник
comment
Поскольку вы не обновляете Graph, вы обновляете только стек, поэтому он не отражает его в методе originator.getGraph()   -  person dkb    schedule 04.02.2019
comment
@dkb, когда я создаю памятку public Memento(Originator originator) { graph = originator.getGraph(); }, граф воспоминаний получает граф создателя, а когда я восстанавливаю памятку public void setMemento(Memento2 memento) { this.graph = memento.getGraph(); }, граф создателя получает граф воспоминаний, то есть он делает наоборот, хотя я не знаю, является ли это графом лучшее решение   -  person Renata P Souza    schedule 04.02.2019


Ответы (1)


Вы ссылаетесь на ту же коллекцию вершин внутри Memento.

Попробуйте изменить следующие классы:

public class Originator<V,E> {
    private Graph<V,E> graph;
    private Caretaker caretaker;

    public Originator(Caretaker caretaker) {
      this.graph = new GraphEdgeList();
      this.caretaker = caretaker;
    }

    public Originator(Originator<V, E> originator) {
         this.graph = new GraphEdgeList((GraphEdgeList) originator.getGraph());
         this.caretaker = originator.getCaretaker();
    }

    public Memento createMemento() {//create new memento
        return new Memento(new Originator(this));
    }

    public void setMemento(Memento memento) {//set memento
       graph = memento.getGraph();
    }

    public Graph getGraph() {
      return graph;
    }

    public Caretaker getCaretaker() {
     return caretaker;
    }
}

Смотрите новые конструкторы.

public class GraphEdgeList<V, E> implements Graph<V, E> {
    private Map<V, Vertex<V>> vertices;

    public GraphEdgeList() {
        this.vertices = new HashMap<>();
    }

    public GraphEdgeList(GraphEdgeList graph) {
         this.vertices = new HashMap<>();
         this.vertices.putAll(graph.getVertices());
    }

    @Override
    public void insertVertex(V vElement) {
        this.vertices.put(vElement, null);
    }

    public Map<V, Vertex<V>> getVertices() {
        return vertices;
    }

    public void setVertices(Map<V, Vertex<V>> vertices) {
        this.vertices = vertices;
    }

    @Override
    public Iterable<Vertex<V>> vertices() {
        return this.vertices.values();
    }

    @Override
    public String toString() {
        return "GraphEdgeList [vertices=" + vertices + "]";
    } 
}
person Valerio Emanuele    schedule 04.02.2019