Ужасный опыт работы с шаблоном команд: есть ли смысл в ООП? - PullRequest
2 голосов
/ 15 декабря 2011

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

class DoWorkCommandMessage { int param; }

class DoWorkCommandHandler : Handler<DoWorkCommandMessage>
{
    Execute(MyObject object) {
       object.DoWork(message.param);
    }
}

class MyObject
{
    void DoWork(int param) {
        _proxy.SendMessage(new DoWorkBinaryMessage(param));
    }
}

Как вы можете видеть, я в основном получаю сообщение, преобразуяэто в вызов метода, который затем преобразует его обратно в сообщение, которое отправляется на другой уровень.

Я чувствую, что здесь что-то не так.

Я закончил рефакторинг MyObject для удалениявсе методы и заменили их простым методом ProcessMessage, который принимает сообщение, переводит его, затем отправляет его.

Это было нормально, за исключением того, что MyObject оказался в основном просто кодом преобразования, а не «объектом»..

Чтобы выполнить модульное тестирование, я должен продолжать вызывать ProcessMessage () вместо простого вызова метода.

Я ищу мысли об этой битве между "обмен сообщениями и преобразованиями" против "сообщения -> метод -> сообщения "подход.Очевидно, что сообщения и методы очень тесно связаны.

1 Ответ

1 голос
/ 15 декабря 2011

Я думаю, что путаница и / или сложность заключаются в том, что вы на самом деле не используете шаблон команд.Вы смешиваете это с обменом сообщениями.Вы даже можете увидеть это в названии вашей команды ... DoWorkCommandMessage.В классическом шаблоне Command работа фактически выполняется объектом Command.При подходе обмена сообщениями сообщения передаются как DTO и выполняются обработчиками.

Для дальнейшей иллюстрации у меня есть приложение, которое использует

AbstractCommand
+ Execute()
+ CanUndo()
+ Undo()
+ CanChain(cmd)
+ Chain(cmd)

Конкретный экземпляр этогокласс:

MoveUnitCommand  // a unit is a graphic piece on a game board
+ UnitId
+ Destination
+ Execute()
  {
      units = Units.Find(UnitId)
      prevCoords = units.Position
      units.Position = Destination
  }
+ CanUndo() { return true; }
+ Undo()
  {
      units = Units.Find(UnitId)
      units.Position = prevCoords 
  }
+ etc, etc

Обратите внимание, что подкласс команды не просто описывает, что делать, он фактически влияет на состояние вашей системы.

...