NazimovDmitrii
8/29/2019 - 10:52 PM

[JS ES6 Паттерн ХРАНИТЕЛЬ (memento)] #js #ES6 #ООП #Паттерны

[JS ES6 Паттерн ХРАНИТЕЛЬ (memento)] #js #ES6 #ООП #Паттерны

/**
 *
 * ПАТТЕРН ХРАНИТЕЛЬ (memento)
 *
 * Паттерн ХРАНИТЕЛЬ (memento) -  Паттерн Хранитель используется для реализации возврата к одному из предыдущих
 * состояний (например, если пользователь выполнил команду «Отменить»).
 * Хранитель – это объект, в котором сохраняется внутреннее состояния другого объекта – хозяина хранителя. Для работы
 * механизма отката нужно, чтобы хозяин предоставил хранитель, когда возникнет необходимость записать контрольную точку
 * состояния хозяина. Только хозяину разрешено помещать в хранитель информацию и извлекать ее оттуда, для других
 * объектов хранитель непрозрачен.
 * УЧАСТНИКИ:

 --- Memento (SolverState) – хранитель:
 – сохраняет внутреннее состояние объекта Originator. Объем сохраняемой информации может быть различным и определяется
 потребностями хозяина;
 – запрещает доступ всем другим объектам, кроме хозяина. По существу, у хранителей есть два интерфейса.
 «Посыльный» Caretaker «видит» лишь «узкий» интерфейс хранителя – он может только передавать хранителя другим объектам.
 Напротив, хозяину доступен «широкиий» интерфейс, который обеспечивает доступ ко всем данным, необходимым для
 восстановления в прежнем состоянии. Идеальный вариант – когда только хозяину, создавшему хранитель, открыт доступ к
 внутреннему состоянию последнего;

 --- Originator (ConstraintSolver) – хозяин:
 – создает хранитель, содержащего снимок текущего внутреннего состояния;
 – использует хранитель для восстановления внутреннего состояния;

 --- Caretaker (механизм отката) – посыльныий:
 – отвечает за сохранение хранителя;
 – не производит никаких операциий над хранителем и не исследует его внутреннее содержимое.
 *
 */

//Как это работает:
// 1. originator.newValue('новое значение') создает новое значение (т.е. меняет состояние originator), записывает
// состояние originator с новым значением в объект memento
// 2. caretaker.SaveState(val) - обьект memento из прошло пункта записывается в хранилище mementos внутри caretaker
// 3. originator.returnState(caretaker.getBackMemento())
//      - caretaker.getBackMemento() возвращает прошлое значение из хранилища mementos, шаг итерации назад
//      - caretaker.getForwardMemento() возвращает будущее значение из хранилища mementos, шаг итерации вперед
//      - originator.returnState() - возвращает состояние originator в прошлое состояние взятое из хранилища mementos caretaker


class Originator { // хозяин
    constructor() {
        console.log('Originator created')
    }

    returnState (Memento){
        this.state = Memento.GetState()
        console.log('State= ' + this.state)
    }

    newValue (state){
        return new Memento(state);
    }
}

class Memento { //хранитель
    constructor(state) {
        this.state = state
        console.log('Memento created. State= ' + this.state)
    }

    GetState (){
        return this.state;
    }

    SetState (state){
        this.state = state;
    }
}

class Caretaker { //посыльный
    constructor() {
        console.log('Caretaker created')
        this.mementos = []
        this.indexMementos = false;
    }

    SaveState(memento) {
        console.log('Caretaker SaveState')
        this.mementos.push(memento)
    }

    getBackMemento() {
        if (this.indexMementos === false) {
            this.indexMementos = this.mementos.length-2;
        } else if (this.indexMementos > 0) {
            this.indexMementos = this.indexMementos-1;
        }
        return this.mementos[this.indexMementos]
    }
    getForwardMemento() {
        if (this.indexMementos >= 0 && this.indexMementos <= this.mementos.length-2) {
            this.indexMementos = this.indexMementos+1;
        }
        return this.mementos[this.indexMementos]
    }
}

    let caretaker = new Caretaker()
    let originator = new Originator()
    const val = originator.newValue('a');
    caretaker.SaveState(val)
    caretaker.SaveState(originator.newValue('b'))
    caretaker.SaveState(originator.newValue('c'))
    originator.returnState(caretaker.getBackMemento())
    originator.returnState(caretaker.getBackMemento())
    originator.returnState(caretaker.getForwardMemento())
    originator.returnState(caretaker.getForwardMemento())

    let caretaker1 = new Caretaker()
    let originator1 = new Originator()
    caretaker1.SaveState(originator1.newValue('z'))
    caretaker1.SaveState(originator1.newValue('zzzz'))
    originator1.returnState(caretaker1.getBackMemento())
    console.log(originator.state)
    console.log(originator1.state)