Вы можете представить себе рабочий процесс шаблона команды следующим образом.
Command
объявляет интерфейс для всех команд, предоставляя простой метод execute (), который просит получателя команды выполнить операцию.
Receiver
знает, что делать, чтобы выполнить запрос.
Invoker
содержит команду и может заставить Command
выполнить запрос, вызвав метод execute.
Client
создает ConcreteCommands
и устанавливает Receiver
для команды.
ConcreteCommand
определяет привязку между действием и получателем.
Когда вызовы Invoker
выполняются, ConcreteCommand
запускает одно или несколько действий на приемнике.
Взгляните на пример кода, чтобы лучше понять ситуацию.
public class CommandDemoEx{
public static void main(String args[]){
// On command for TV with same invoker
Receiver r = new TV();
Command onCommand = new OnCommand(r);
Invoker invoker = new Invoker(onCommand);
invoker.execute();
// On command for DVDPlayer with same invoker
r = new DVDPlayer();
onCommand = new OnCommand(r);
invoker = new Invoker(onCommand);
invoker.execute();
}
}
interface Command {
public void execute();
}
class Receiver {
public void switchOn(){
System.out.println("Switch on from:"+this.getClass().getSimpleName());
}
}
class OnCommand implements Command{
private Receiver receiver;
public OnCommand(Receiver receiver){
this.receiver = receiver;
}
public void execute(){
receiver.switchOn();
}
}
class Invoker {
public Command command;
public Invoker(Command c){
this.command=c;
}
public void execute(){
this.command.execute();
}
}
class TV extends Receiver{
public TV(){
}
public String toString(){
return this.getClass().getSimpleName();
}
}
class DVDPlayer extends Receiver{
public DVDPlayer(){
}
public String toString(){
return this.getClass().getSimpleName();
}
}
выход:
java CommandDemoEx
Switch on from:TV
Switch on from:DVDPlayer
Чтобы ответить на ваш вопрос:
Я читал, что клиент знает о конкретном получателе и конкретной команде, и обычно это клиент, настраивающий объект-получатель в конкретном командном объекте. Тогда почему говорят, что он разделяет отправителя и получателя
Чтобы стандартизировать слова, замените «отправитель» на «вызывающий». Теперь пройдемся по коду.
Invoker simply executes the ConcreteCommand
(в данном случае OnCommand) путем передачи ConcreteReceiver.
ConcreteCommand executes Command
через ConcreteReceiver, т.е. ConcreteCommand defines binding between Action and Receiver.
- Если вы видите рабочий процесс, Invoker не изменяется с помощью дополнительных команд, и вы можете добавить бизнес-логику в
execute()
метод Invoker, например java.lang.Thread, который был объяснен, как показано ниже.
- Таким образом
Client (sender) and Receiver are loosely couple through Invoker, which has knowledge of what command to be executed
.
Пример темы из этого ссылка
Вы можете создать поток, реализовав объект Runnable.
Thread t = new Thread (new MyRunnable()).start();
=>
Invoker invoker = new Invoker(new ConcreteCommand());
invoker.start()
и у вас есть логика в start () для вызова ConcreteCommand.execute (), который в приведенном выше случае запускается ().
Метод start () вызовет метод run () в потоке. Что произойдет, если вы вызовете метод run () напрямую? Он не будет рассматриваться как цепочка.
Как и метод start () этого потока, вы можете добавить некоторую бизнес-логику в Invoker.
public synchronized void start() {
/**
* This method is not invoked for the main method thread or "system"
* group threads created/set up by the VM. Any new functionality added
* to this method in the future may have to also be added to the VM.
*
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
group.add(this);
start0();
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
private native void start0(); // Native code is not here but this method will call run() method
public void run() {
if (target != null) {
target.run();
}
}
ИЗМЕНИТЬ:
По вашему последнему запросу
Здесь мы создаем объект команды, объект Receiver и объект Invoker. Затем передаем объект-получатель в объекте команды, а затем передаем объект команды в объект invoker. Это мы делаем для каждого приемника, как здесь для TV и DVDPlayer. Также в методе «main» объект TV и DVDPlayer известны и фактически создаются. Мы можем просто выполнить tvObject.switchOn () и dvdPlayer.switchOn (). Как помогает шаблон Command
Клиенту не нужно беспокоиться об изменениях в классе Receiver
. Invoker
напрямую работает с ConcreteCommand
, у которого есть объект Receiver
. Receiver
объект может измениться с siwtchOn
() на switchOnDevice
() в будущем. Но взаимодействие с клиентом не меняется.
Если у вас есть две разные команды, такие как switchOn
() и switchOff
(), вы все равно можете использовать тот же Invoker
.
person
Ravindra babu
schedule
09.02.2016