Требуется ли ссылка на получателя для правильной реализации шаблона проектирования команд? - PullRequest
0 голосов
/ 12 марта 2012

Для шаблонов проектирования GoF ( wikipedia ), экземпляр ConcreteCommand должен (должен?) Иметь ссылку (ссылку) на экземпляр Receiver. У меня есть следующая реализация команды:

internal class PutBlockOntoBlockCommand : ICommand {
    private readonly int _srcTower;
    private readonly int _dstTower;

    public PutBlockOntoBlockCommand(int srcTower, int dstTower) {
        _srcTower = srcTower;
        _dstTower = dstTower;
    }

    public void Execute(Robot robot, Construction construction) {
        robot.MoveBlocks(_srcTower, _dstTower, construction);
    }
}

Эта команда инструктирует робота перемещать блоки на строительной площадке. Обратите внимание, что экземпляр команды не имеет ссылки на экземпляр приемника (робота); вместо этого команда полагается на Invoker (в моем случае RobotCommandCenter) для предоставления экземпляра Robot для выполнения команды.

Я убежден, что для того, чтобы команда была командой, она должна только инкапсулировать намерение и должна не отвечать за указание цели команды. В моем случае, как пользователь, мне все равно, какой робот будет использоваться для выполнения задания.

Итак, мой вопрос: технически допустимо ссылаться на представленную реализацию как «Шаблон проектирования команд»?

1 Ответ

1 голос
/ 13 марта 2012

Во-первых, в полиции нет шаблонов. Он всегда открыт для интерпретации и окрашен в оттенки серого.

Во-вторых, Википедия не так хороша, как первоначальный том, вложите деньги в книгу:)

GoF перечисляет намерение шаблона Command как:

Инкапсулирует запрос как объект, что позволяет вам параметризировать клиенты с разными запросами, очередями или журналами запросов и поддержкой отменяемые операции.

Если вы встретите хотя бы одно из этих намерений, я бы сказал, что вы можете назвать это производной от команды.

В общем, вы можете сказать, что что-то - это команда, если она содержит логику для реализации или вызова желаемого эффекта, освобождая владельца ссылки на команду от работы с этими деталями. Часто это настолько инкапсулировано, что вы можете делать классные вещи, такие как помещать их в список и использовать общий метод Execute, определенный в базе, для очень чистого выполнения Redo и Undo.

Если ваш базовый класс определил «Выполнить», а ваш вызывающий код передает все команды, на которые ссылается робот, тогда у вас есть команда, но та, которая имеет аспекты стратегии или веса, которые позволяют вам изменять назначение команд. Я могу видеть использование для этого, хотя за счет таких вещей, как отменить / повторить.

...