Шаблон проектирования команд - является ли Invoker необязательным?
Является ли класс Invoker необязательным в шаблоне проектирования Command? Клиент должен создать конкретную команду и получатель для этой команды. Всегда ли клиент должен создавать экземпляр Invoker и передавать объект команды объекту Invoker. Позже, когда клиенту нужно выполнить команду, клиент просто запрашивает объект Invoker, а Invoker выполняет команду (может быть, немедленно или может поставить команду в очередь для последующего выполнения).
Или это наоборот? Если клиенту нужно выполнить команду синхронно, он будет ссылаться на команду, используя интерфейс базового класса, но будет создавать конкретную команду и получателя. Всякий раз, когда клиенту потребуется выполнить команду, клиент просто вызовет метод execute для переменной команды базового класса? Когда возникнет необходимость в некоторой дополнительной логике того, когда команда должна быть выполнена, будет использоваться класс Invoker, чтобы сохранить эту дополнительную логику, и клиент будет взаимодействовать с объектом Invoker для выполнения команды?
2 ответа
Целями шаблона Command обычно являются: 1) создание набора различных операций с одним и тем же типом, чтобы они могли обрабатываться одним и тем же кодом; 2) отделение / создание операции отдельной операции от вызова операции. Приемник явно требуется для цели 2.
Если вы вызываете сразу после создания или если Reciever играет роль вызывающего, то не существует одноцелевого, отдельного вызывающего. Значит ли это, что нет призывателя - это действительно философский вопрос:)
Посмотрите на это так: вы / можете / отделить создание, планирование и вызов. Это не значит, что вы должны реализовать их как три отдельных класса. Это просто логические роли, которые участвуют в жизненном цикле шаблона Command.
РЕДАКТИРОВАТЬ: Я предполагаю, что принцип единой ответственности утверждает, что вы должны разделить их, но есть такая вещь, как смысл commen:) Местные условия могут и должны соблюдаться.
Как мы знаем, java.lang.Runnable является одним из примеров шаблонов команд, где класс Thread работает как вызывающий. Мы передаем объект класса Runnable классу Thread и говорим start/run.
Но мы никогда не создаем клиентский класс, который может вызывать основной поток.
Так что призыватель не является обязательным, но он не тесно связан с клиентом. Таким образом, UML шаблона команды никогда не показывает какую-либо связь между клиентским классом и классом invoker.
Еще один ответ связан с этим вопросом.