每日学一个设计模式22——命令模式

命令模式(命令也是类)

用处

请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

角色

  • Command(命令)
    该角色负责定义命令的接口(API)
  • ConcreteCommand(具体的命令)
    该角色负责实现Command角色中定义的接口(API)。
  • Recevier(接收者)
    该角色是Command角色执行命令时的对象,也可以称其为命令接收者。
  • Client(请求者)
    该角色负责生成ConcreteCommand并分配Receiver角色。
  • Invoker(发动者)
    该角色是开始执行命令的角色,它会调用在Command角色中定义的接口(API)。

类图

每日学一个设计模式22——命令模式_第1张图片
由类图可知

  • Invoker通过Command接口聚合了ConcreteCommand,在ConcreteCommand中又聚合Receiver
  • Invoker调用ConcreteCommand中的execute方法发出命令,ConcreteCommand再调用Receiver的action方法接受命

举例

//Invoker和Client角色
public class Main extends JFrame implements ActionListener, MouseMotionListener,WindowListener {
    private MacroCommand history = new MacroCommand();
    private DrawCanvas canvas = new DrawCanvas(400,400,history);
    private JButton clearButton = new JButton("clear");
    public Main(String title){
        super(title);
        this.addWindowListener(this);
        canvas.addMouseMotionListener(this);
        clearButton.addActionListener(this);
        Box buttonBox = new Box(BoxLayout.X_AXIS);
        buttonBox.add(clearButton);
        Box mainBox = new Box(BoxLayout.Y_AXIS);
        mainBox.add(buttonBox);
        mainBox.add(canvas);
        getContentPane().add(mainBox);
        pack();
        show();
    }
    public void actionPerformed(ActionEvent e){
        if(e.getSource() == clearButton){
            history.clear();
            canvas.repaint();
        }
    }

    public void mouseMoved(MouseEvent e){
    }
    public void mouseDragged(MouseEvent e){
        Command cmd = new DrawCommand(canvas,e.getPoint());
        history.append(cmd);
        cmd.execute();
    }
    public void windowClosing(WindowEvent e){
        System.exit(0);
    }
    public void windowActivated(WindowEvent e){}
    public void windowClosed(WindowEvent e){}
    public void windowDeactivated(WindowEvent e){}
    public void windowDeiconified(WindowEvent e){}
    public void windowIconified(WindowEvent e){}
    public void windowOpened(WindowEvent e){}

    public static void main(String[] args){
        new Main("Command Pattern Sample");
    }
}
//Command
interface Command{
    void execute();
};

//ConcreteCommand
class MacroCommand implements Command{
    //命令的集合
    private Stack commands = new Stack();
    public void execute(){
        Iterator it = commands.iterator();
        while(it.hasNext()){
            ((Command)it.next()).execute();
        }
    }
    //添加命令
    public void append(Command cmd){
        if(cmd != this){
            commands.push(cmd);
        }
    }

    //删除最后一条命令
    public void clear(){
        commands.clear();
    }
}

//ConcreteCommand角色
class DrawCommand implements Command{
    //绘制对象
    protected Drawable drawable;
    //绘制位置
    protected Point position;

    public DrawCommand(Drawable drawable,Point position){
        this.drawable = drawable;
        this.position = position;
    }

    public void execute(){
        drawable.draw(position.x,position.y);
    }
}

interface Drawable{
    void draw(int x,int y);
}

//Receiver角色
class DrawCanvas extends Canvas implements Drawable{
    private Color color = Color.red;
    private int radius = 6;
    private MacroCommand history;
    public DrawCanvas(int width,int height,MacroCommand history){
        setSize(width,height);
        setBackground(Color.white);
        this.history = history;
    }
    public void paint(Graphics g){
        history.execute();
    }
    public void draw(int x,int y){
        Graphics g = getGraphics();
        g.setColor(color);
        g.fillOval(x-radius,y-radius,radius*2,radius*2);
    }
}

每日学一个设计模式22——命令模式_第2张图片

总结

  • 符合开闭原则
  • 实现行为请求者-行为实现者之间的解耦

你可能感兴趣的:(命令模式,设计模式)