Шаблон команды Undo/Redo: какие-то проблемы с моим подходом?

Я хочу реализовать шаблон команды для поддержки отмены/повтора в моем приложении. Данные очень тесно связаны друг с другом, поэтому есть некоторые последующие последствия изменения некоторых моих объектов, которые я также хочу отменить. Меня больше всего беспокоит то, куда я должен поместить код, выполняющий подчиненные команды. Например:

class:MoveObjectCommand
{
    private hierarchicalObject:internalObject;

    public MoveObjectCommand(hierarchicalObject:newObject)
    {
        internalObject = newObject;
    }

    public Execute()
    {
        internalObject.Location = someNewLocation;

        foreach(hierarchicalObject:child in internalObject.Children)
        {
            if(someNewLocation = specialPlace)
            {
                var newCommand:MoveObjectCommand = new MoveObjectCommand(child)

                CommandManager.add(newCommand);
            }
        }

    }

    public Undo()
    {
        internalObject.location = oldLocation;
    }
}

Насколько я могу судить, что-то вроде этого будет работать нормально, но я не могу понять, куда на самом деле должна идти большая часть исполняемого кода. Должен ли hierarchicalObject иметь метод .changeLocation(), который добавляет все последующие команды, или они должны быть в самой команде, как показано выше? Единственная разница, о которой я могу думать, заключается в том, что в приведенном выше примере MoveObjectCommand нужно было бы вызывать для последующих изменений для обработки, тогда как в другом случае ее можно было бы вызвать без команды и по-прежнему обрабатывать таким же образом (может иметь негативные последствия для отслеживания шагов отмены/повтора). Я слишком много думаю об этом? Куда бы вы его поместили и почему (очевидно, этот пример не затрагивает всех аспектов, но есть ли какие-либо общие рекомендации по использованию шаблона команды?).


person Ocelot20    schedule 06.01.2011    source источник


Ответы (1)


похоже, у вас должен быть метод changeLocation() в модели (я полагаю, hierarchicalObject). просто сохраните новое местоположение и объект в команде.

для отмены/повтора вам понадобится список или два для команд.

похоже, что ваш hierarchicalObject может быть http://en.wikipedia.org/wiki/Composite_pattern, так что взгляните на макрокоманду в книге Gang-of-Four. также просмотрите: http://en.wikipedia.org/wiki/Command_pattern.

Кристофер Александер говорит: «Каждый паттерн описывает проблему, которая снова и снова возникает в нашей среде, а затем описывает суть решения этой проблемы таким образом, что вы можете использовать это решение миллион раз, ни разу не выполняя никаких действий. то же самое дважды».

person Ray Tayek    schedule 06.01.2011
comment
Да, я тоже начинаю так думать, немного подумав об этом. Если бы код находился в объекте команды, это означало бы, что иерархический объект можно изменить, и история команд не будет сохранена. - person Ocelot20; 06.01.2011