В чем разница между шаблоном проектирования Memento и Command?

Я успешно закодировал пасьянс на Java, и теперь меня попросили реализовать отмену / возврат поверх моего дизайна.

Мой план состоял в том, чтобы сохранить список или стек движений, выполненных пользователем, и если пользователь хочет отменить, я бы 1. проверил, может ли пользователь отменить (т.е. есть ходы в списке или стеке), затем 2. отменить последние два хода, которые я сохранил (т.е. ход «от», откуда я переместил карту, и ход «до», куда я переместил карту).

Для повтора я бы просто повторил ходы, в зависимости от того, насколько далеко пользователь выполнил действие отмены (например, если бы они дважды нажали отменить, я бы был, по крайней мере, (размер списка - 4) вниз по моему списку или стеку ).

Думаю, они будут реализованы в таком интерфейсе:

public interface UndoRedo {
    void undo();
    void redo();
 }

Реализую ли я Memento, шаблон проектирования Command или ни то, ни другое? У меня проблемы с пониманием того, как выглядят два шаблона проектирования в контексте отмены / возврата для этой игры. Я также новичок в Java OOP и шаблонах проектирования в целом.


person B.M. Corwen    schedule 04.03.2018    source источник
comment
now I have been asked to implement... если это домашнее задание, см. Как мне задавать домашние вопросы и отвечать на них?   -  person Fuhrmanator    schedule 05.03.2018


Ответы (3)


Судя по тому, что вы описываете, вы, кажется, реализуете шаблон Command.

Команда фиксирует всю информацию, необходимую для выполнения определенного действия (не обязательно для отмены этого действия). Ваши движения - это в основном команды.

Memento - это способ сохранить состояние, чтобы его можно было восстановить. Предположим, у вас есть такой класс, как GameState, который представляет текущее состояние игры. Вы бы реализовали Memento, если бы в вашем GameState были такие методы, как GameStateBackup createBackup() и restoreFromBackup(GameStateBackup).

Рассмотрим шахматную партию, в которой вы хотите отменить последние x ходов.

Один из способов сделать это - записывать все ходы. Тогда вы могли либо «отменить» ходы. Или просто «переиграйте» первые n-x ходов. Это был бы командный подход.

Другой способ - сохранить последние x состояний игры (и иметь возможность их восстановить). Это подход Memento.

На самом деле вы можете использовать оба шаблона вместе. Например, когда реализация «отмены» неосуществима, вы можете записывать состояние игры до / после каждого хода, чтобы сделать ходы отменяемыми.

person lexicore    schedule 04.03.2018

Если вы выполняете отмену / повторение, выполняя команды в состоянии, это шаблон команды. Если вы отменяете / повторяете, заменяя состояние из кеша состояний, это памятный знак.

Разница между паттернами Command и Memento для UNDO / REDO заключается в том, что в шаблоне Command вы повторно выполняете команды в том же порядке, в котором изменились атрибуты состояния, а с Memento вы полностью заменяете состояние, извлекая из кеш / магазин. Шаблоны проектирования в Python: ASIN B08XLJ8Z2J

person Sean Bradley    schedule 18.10.2019

Ни один. Вы сохраняете предыдущий ввод как состояние и разрешаете действия с данными.

Memento хранит вычисленные значения для каждого уникального ввода для детерминированных функций и возвращает сохраненное значение, если тот же ввод снова появляется.

Команда объединяет исполняемый код и его ввод в виде единого объекта, который может быть выполнен позже, передав ввод в исполняемый файл.

Это близко к Command, но не похоже, что это Command, потому что это не независимое асинхронное действие.

person Bohemian♦    schedule 04.03.2018
comment
Это описание Memento подразумевает, что это не более чем кеширование. Это чрезмерное упрощение. Также я думаю, что описание Command должно заканчиваться передачей объекта исполнителю. - person jaco0646; 05.03.2018