Command Mode -Command Pattern

In the software development system, there are often there is a close coupling between "requester method" and "implementers approach." This is not conducive to the expansion and maintenance of software functionality. For example, want to conduct "undo, redo, record" and processing is very inconvenient, so "the requester and the method of implementation of the method's how to decouple?" Becomes very important, command mode can be a good solution this problem.

In real life, there are many such examples, for example, the TV remote control (command sender) to the TV via remote control button (specific command) (command receivers), as well as "function keys" and on the computer keyboard.

The definition and characteristics of command mode

Defined command (Command) mode are as follows: Encapsulate a request for an object, so that execution of the request and Responsibility requesting separated. Such communication between the command object so easy to command objects for storage, transfer, recall, and increased management.

The main advantage of command mode is as follows.

(1) reduce the coupling system. Since no direct reference between the requester and the recipient, thus achieving complete decoupling between the requester and the recipient, the same requestor may correspond to different recipients, the same, the recipient may be the same for different requesters use, has a good independence between the two.

(2) The new commands can be easily added to the system. Due to the addition of new concrete command class it does not affect the other classes, so ask the sender and receiver decoupling
add new concrete command class easily, without modifying the original system source code, class code and even customers, to meet the "principle of opening and closing "requirements.

(3) can be relatively easily design a command queue or the macro command (command combination).

(4) for the withdrawal (the Undo) recovery requests and (Redo) operation provides a design and implementation

The disadvantages are:

Use the command mode may cause some systems have too many specific command class. Because for each call to the operation of the recipient's request will need to design a specific command class, so in some systems may need to provide a large amount of concrete command class, which will affect the command mode.

Architecture and Implementation of command mode

System operation related command may be abstracted into the caller associated with the implementor separation, has the following structure.

1. Structure Model

Command mode includes the following major role.

  1. Abstract class command (Command) Role: declare an interface to execute the command, abstract method has to execute commands execute ().
  2. Specific command role (Concrete Command) role: is a concrete realization of the abstract class Command class, which has receivers object and function by calling the recipient to complete the operation command to be executed.
  3. Realization / Receiver (Receiver) role: perform related operations command function is to realize who the specific orders of business objects.
  4. The caller / requester (Invoker) roles: the sender's request, it usually has a lot of command object, and to implement the relevant request by accessing the command object, it does not directly access the recipient.


The structure shown in Figure 1.
 

Command mode structure of FIG.
Command mode structure of FIG. 1 FIG.

2. Mode of realization

Command mode code is as follows:

package command;
public class CommandPattern
{
    public static void main(String[] args)
    {
        Command cmd=new ConcreteCommand();
        Invoker ir=new Invoker(cmd);
        System.out.println("客户访问调用者的call()方法...");
        ir.call();
    }
}
//调用者
class Invoker
{
    private Command command;
    public Invoker(Command command)
    {
        this.command=command;
    }
    public void setCommand(Command command)
    {
        this.command=command;
    }
    public void call()
    {
        System.out.println("调用者执行命令command...");
        command.execute();
    }
}
//抽象命令
interface Command
{
    public abstract void execute();
}
//具体命令
class ConcreteCommand implements Command
{
    private Receiver receiver;
    ConcreteCommand()
    {
        receiver=new Receiver();
    }
    public void execute()
    {
        receiver.action();
    }
}
//接收者
class Receiver
{
    public void action()
    {
        System.out.println("接收者的action()方法被调用...");
    }
}
Operating results of the program are as follows:
Customer access the caller's call () method ... 
the caller execute command command ... 
the recipient's action () method is called ...

Application examples of command mode

[Example 1] Examples achieve customer go to a restaurant to eat breakfast with the command mode.

Analysis: Customers can choose to go to a restaurant having breakfast rice rolls, rice noodles and wonton, etc., customers can choose to several waiter over breakfast, the waiter the customer's request to the relevant chef to make. The point here is equivalent breakfast "order", the waiter is equivalent to "caller", the chef equivalent of "receiver", is achieved with the appropriate command mode.

First, define a class breakfast (Breakfast), which is an abstract Command class, abstract method cooking (), explain what to do; and then define subclasses like rice rolls (ChangFen), ravioli class (HunTun) and Pho class ( HeFen), which is a specific command class that implements the cooking () method of class breakfast, but they do not specifically, but to the chef to make concrete; concrete class chef cooks have rice rolls (ChangFenChef), ravioli eclipse chef ( HunTunChef) and Pho cook (HeFenChef), they are the recipient of the command, since the present example of FIG cook to cook display ( renderings to be displayed here to download ), so the cook each sub-class is defined as JFrame class; Finally, the definition of class waiter (waiter), it receives the client's request for cooking, cooking and issue the command. Client class by class attendant la carte, FIG. 2 is a configuration diagram of FIG.
 

Customer eat breakfast at the restaurant structure diagram
Figure 2 customers eating breakfast in a restaurant structure diagram


Code is as follows:

package command;
import javax.swing.*;
public class CookingCommand
{
    public static void main(String[] args)
    {
        Breakfast food1=new ChangFen();
        Breakfast food2=new HunTun();
        Breakfast food3=new HeFen();
        Waiter fwy=new Waiter();
        fwy.setChangFen(food1);//设置肠粉菜单
        fwy.setHunTun(food2);  //设置河粉菜单
        fwy.setHeFen(food3);   //设置馄饨菜单
        fwy.chooseChangFen();  //选择肠粉
        fwy.chooseHeFen();     //选择河粉
        fwy.chooseHunTun();    //选择馄饨
    }
}
//调用者:服务员
class Waiter
{
    private Breakfast changFen,hunTun,heFen;
    public void setChangFen(Breakfast f)
    {
        changFen=f;
    }
    public void setHunTun(Breakfast f)
    {
        hunTun=f;
    }
    public void setHeFen(Breakfast f)
    {
        heFen=f;
    }
    public void chooseChangFen()
    {
        changFen.cooking();
    }
    public void chooseHunTun()
    {
        hunTun.cooking();
    }
    public void chooseHeFen()
    {
        heFen.cooking();
    }
}
//抽象命令:早餐
interface Breakfast
{
    public abstract void cooking();
}
//具体命令:肠粉
class ChangFen implements Breakfast
{
    private ChangFenChef receiver;
    ChangFen()
    {
        receiver=new ChangFenChef();
    }
    public void cooking()
    {       
        receiver.cooking();
    }
}
//具体命令:馄饨
class HunTun implements Breakfast
{
    private HunTunChef receiver;
    HunTun()
    {
        receiver=new HunTunChef();
    }
    public void cooking()
    {
        receiver.cooking();
    }
}
//具体命令:河粉
class HeFen implements Breakfast
{
    private HeFenChef receiver;
    HeFen()
    {
        receiver=new HeFenChef();
    }
    public void cooking()
    {
        receiver.cooking();
    }
}
//接收者:肠粉厨师
class ChangFenChef extends JFrame
{   
    private static final long serialVersionUID = 1L;
    JLabel l=new JLabel();
    ChangFenChef()
    {
        super("煮肠粉");
        l.setIcon(new ImageIcon("src/command/ChangFen.jpg"));
        this.add(l);
        this.setLocation(30, 30);
        this.pack();
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   
    }
    public void cooking()
    {
        this.setVisible(true);
    }
}
//接收者:馄饨厨师
class HunTunChef extends JFrame
{
    private static final long serialVersionUID=1L;
    JLabel l=new JLabel();
    HunTunChef()
    {
        super("煮馄饨");
        l.setIcon(new ImageIcon("src/command/HunTun.jpg"));
        this.add(l);
        this.setLocation(350, 50);
        this.pack();
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
    }
    public void cooking()
    {
        this.setVisible(true);
    }
}
//接收者:河粉厨师
class HeFenChef extends JFrame
{
    private static final long serialVersionUID=1L;
    JLabel l=new JLabel();
    HeFenChef()
    {
        super("煮河粉");
        l.setIcon(new ImageIcon("src/command/HeFen.jpg"));
        this.add(l);
        this.setLocation(200, 280);
        this.pack();
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public void cooking()
    {
        this.setVisible(true);
    }
}
 

Scenarios command mode

Command mode is typically used in the scene.

  1. When the system requires that the caller needs to be decoupled from the receiver request, command mode so that the caller does not directly interact and receiver.
  2. When the system needs random order request or frequently add or delete command, the command mode is more convenient to implement these functions.
  3. When the system needs to perform a set of operations, command mode may be defined to achieve this function macros.
  4. When the system needs to support Undo command (the Undo) and recovery operation (Redo) operation, a command object can be stored, using the memo mode is achieved.

Extended command mode

In software development, sometimes in front of the command mode and learn mode combination used in combination, which constitutes a macro mode, also called combined command mode. Macro command comprising a set of commands, it acts as a dual role and caller specific command, the recursive call that it contains all commands which, when executed, its specific structure is shown in Figure 3.
 

FIG configuration command mode combination
FIG 3 is a configuration diagram of a combination of command mode


Code is as follows:

 
package command;
import java.util.ArrayList;
public class CompositeCommandPattern
{
    public static void main(String[] args)
    {
        AbstractCommand cmd1=new ConcreteCommand1();
        AbstractCommand cmd2=new ConcreteCommand2();
        CompositeInvoker ir=new CompositeInvoker();
        ir.add(cmd1);
        ir.add(cmd2);
        System.out.println("客户访问调用者的execute()方法...");
        ir.execute();
    }
}
//抽象命令
interface AbstractCommand
{
    public abstract void execute();
}
//树叶构件: 具体命令1
class ConcreteCommand1 implements AbstractCommand
{
    private CompositeReceiver receiver;
    ConcreteCommand1()
    {
        receiver=new CompositeReceiver();
    }
    public void execute()
    {       
        receiver.action1();
    }
}
//树叶构件: 具体命令2
class ConcreteCommand2 implements AbstractCommand
{
    private CompositeReceiver receiver;
    ConcreteCommand2()
    {
        receiver=new CompositeReceiver();
    }
    public void execute()
    {       
        receiver.action2();
    }
}
//树枝构件: 调用者
class CompositeInvoker implements AbstractCommand
{
    private ArrayList<AbstractCommand> children = new ArrayList<AbstractCommand>();   
    public void add(AbstractCommand c)
    {
        children.add(c);
    }   
    public void remove(AbstractCommand c)
    {
        children.remove(c);
    }   
    public AbstractCommand getChild(int i)
    {
        return children.get(i);
    }   
    public void execute()
    {
        for(Object obj:children)
        {
            ((AbstractCommand)obj).execute();
        }
    }    
}
//接收者
class CompositeReceiver
{
    public void action1()
    {
        System.out.println("接收者的action1()方法被调用...");
    }
    public void action2()
    {
        System.out.println("接收者的action2()方法被调用...");
    }
}


Operating results of the program are as follows:

Customer access the caller's execute () method ... 
recipient action1 () method is called ... 
recipient action2 () method is called ...


Of course, the same memo can command mode (Memento) mode used in combination, so that it becomes a revocable command mode, which will be described later.

Guess you like

Origin blog.csdn.net/yucaixiang/article/details/94552841