设计模式学习笔记——命令(Command)模式

来源:互联网 发布:win10 卸载软件 编辑:程序博客网 时间:2024/05/17 15:36

设计模式学习笔记——命令(Command)模式

@(设计模式)[设计模式, 命令模式, command]

  • 设计模式学习笔记命令Command模式
    • 基本介绍
    • 命令案例
      • 类图
      • 实现代码
        • Command接口
        • MacroCommand类
        • Drawable接口
        • DrawCommand类
        • DrawCanvas类
        • 测试类
        • 运行结果
    • 命令模式中的角色
      • Command命令
      • ConcreteCommand具体的命令
      • Receiver接收者
      • Client请求者
      • Invoker发动者
      • 类图
      • 时序图

基本介绍

将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。

命令案例

类图

命令案例类图

实现代码

Command接口

package com.pc.command.example.command;/** * 命令接口 * Created by Switch on 2017/3/31. */public interface Command {    /**     * 执行     */    void execute();}

MacroCommand类

package com.pc.command.example.command;import java.util.Iterator;import java.util.Stack;/** * 大量命令类 * Created by Switch on 2017/3/31. */public class MacroCommand implements Command {    /**     * 命令的集合     */    private Stack<Command> commands = new Stack<>();    @Override    public void execute() {        Iterator<Command> it = commands.iterator();        while (it.hasNext()) {            it.next().execute();        }    }    /**     * 添加命令     *     * @param cmd 命令     */    public void append(Command cmd) {        if (cmd != this) {            commands.push(cmd);        }    }    /**     * 删除最后一条命令     */    public void undo() {        if (!commands.empty()) {            commands.pop();        }    }    /**     * 删除所有命令     */    public void clear() {        commands.clear();    }}

Drawable接口

package com.pc.command.example.drawer;/** * 绘图接口 */public interface Drawable {    /**     * 绘制     *     * @param x x坐标     * @param y y坐标     */    void draw(int x, int y);}

DrawCommand类

package com.pc.command.example.drawer;import com.pc.command.example.command.Command;import java.awt.*;/** * 绘图命令类 */public class DrawCommand implements Command {    /**     * 绘制对象     */    protected Drawable drawable;    /**     * 绘制位置     */    private Point position;    public DrawCommand(Drawable drawable, Point position) {        this.drawable = drawable;        this.position = position;    }    @Override    public void execute() {        drawable.draw(position.x, position.y);    }}

DrawCanvas类

package com.pc.command.example.drawer;import com.pc.command.example.command.MacroCommand;import java.awt.*;/** * 绘制面板类 */public 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;    }    @Override    public void paint(Graphics g) {        history.execute();    }    @Override    public void draw(int x, int y) {        Graphics g = getGraphics();        g.setColor(color);        g.fillOval(x - radius, y - radius, radius * 2, radius * 2);    }}

测试类

package com.pc.command.example.test;import com.pc.command.example.command.Command;import com.pc.command.example.command.MacroCommand;import com.pc.command.example.drawer.DrawCanvas;import com.pc.command.example.drawer.DrawCommand;import javax.swing.*;import java.awt.event.*;/** * MacroCommand Tester. * * @author Switch * @version 1.0 */public class CommandTest 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 CommandTest(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();    }    // ActionListener接口中的方法    public void actionPerformed(ActionEvent e) {        if (e.getSource() == clearButton) {            history.clear();            canvas.repaint();        }    }    // MouseMotionListener接口中的方法    public void mouseMoved(MouseEvent e) {    }    public void mouseDragged(MouseEvent e) {        Command cmd = new DrawCommand(canvas, e.getPoint());        history.append(cmd);        cmd.execute();    }    // WindowListener接口中的方法    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 CommandTest("Command Pattern Sample");    }}

运行结果

这里写图片描述

命令模式中的角色

Command(命令)

Command角色负责定义命令的接口(API)。在案例中,由Command接口扮演此角色。

ConcreteCommand(具体的命令)

ConcreteCommand角色负责实现在Command角色中定义的接口(API)。在案例中,由MacroCommand类和DrawCommand类扮演此角色。

Receiver(接收者)

Receiver角色是Command角色执行命令时的对象,也可以称其为命令接收者。在案例中,由DrawCanvas类接收DrawCanvas类和DrawCommand类扮演此角色。

Client(请求者)

Client角色负责生成ConcreteCommand角色并分配Receiver角色。在案例中,由测试类扮演此角色。在响应鼠标拖拽事件时,它生成了DrawComrnand类的实例,并将扮演Receiver角色的DrawCanvas类的实例传递给了DrawCommand 类的构造函数。

Invoker(发动者)

Invoker角色是开始执行命令的角色,它会调用在Command角色中定义的接口(API)。在案例中,由测试和DrawCanvas类扮演此角色。这两个类都调用了Command接口中的execute方法。测试类同时扮演了Client角色和Invoker角色。

类图

命令模式类图

时序图

命令模式时序图

GitHub:DesignPatternStudy

——————参考《图解设计模式》

0 0
原创粉丝点击