图解设计模式(二十二)Command 模式

读书笔记 仅供参考

简述

Command 模式是使用表示命令的类来代替方法的调用,这样就可以管理工作的历史记录。

角色和 UML

Command

定义命令的接口(API)。

ConcreteCommand

负责实现在 Command 角色中定义的接口(API)。

Receiver

是 Command 角色执行命令时的对象,可以称为命令接收者。

Client

负责生成 ConcreteCommand 角色并分配 Receiver 角色。

Invoker

是开始执行命令的角色,会调用 Command 角色中定义的接口(API)。

UML

例子

例程是一个简单的画图程序,随着鼠标点击拖拽,可以进行绘画,每一个点的绘画就是一个 Command。可以将之前的 Command 保存下来,以供之后的重绘使用,或者实现 undo 需求。

UML 

// Command 角色,只需要定义一个方法
public interface Command {
    void execute();
}
// 表示绘制对象的接口,也是 Receiver 角色
public interface Drawable {
    void draw(int x, int y);
}
// 绘制一个点的命令
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);
    }
}
//由多条命令整合的命令
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();
        }
    }

    //添加命令
    public void append(Command command) {
        if (command != this) {
            commands.push(command);
        }
    }

    //删除最后一条命令,达到撤销命令的目的
    public void undo() {
        if (!commands.empty()) {
            commands.pop();
        }
    }

    //删除所有命令
    public void clear() {
        commands.clear();
    }
}
// 画板
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;
    }

    // 全部重新绘制
    public void paint(Graphics graphics) {
        history.execute();
    }

    @Override
    public void draw(int x, int y) {
        Graphics graphics = getGraphics();
        graphics.setColor(color);
        graphics.fillOval(x - radius, y - radius, radius * 2, radius * 2);
    }
}
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) throws HeadlessException {
        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 static void main(String[] args) {
        new Main("Command Pattern Sample");
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == clearButton) {
            history.clear();
            canvas.repaint();
        }
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        Command cmd = new DrawCommand(canvas, e.getPoint());
        history.append(cmd);
        cmd.execute();
    }

    @Override
    public void mouseMoved(MouseEvent e) {

    }

    @Override
    public void windowOpened(WindowEvent e) {
    }

    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }

    @Override
    public void windowClosed(WindowEvent e) {
    }

    @Override
    public void windowIconified(WindowEvent e) {
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
    }

    @Override
    public void windowActivated(WindowEvent e) {
    }

    @Override
    public void windowDeactivated(WindowEvent e) {
    }
}

结果

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值