设计模式(二十二)-命令模式(Command Pattern)——命令也是类

原创 2018年02月11日 09:21:36

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

Command.java

package com.test.dp.Command.Sample.command;

//表示命令的接口
public interface Command {
    public abstract void execute();
}
MacroCommand.java

package com.test.dp.Command.Sample.command;

import java.util.Stack;
import java.util.Iterator;

//表示“由多条命令合成的命令”的类
public 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 undo() {
        if (!commands.empty()) {
            commands.pop();
        }
    }
    // 删除所有命令
    public void clear() {
        commands.clear();
    }
}
DrawCommand.java

package com.test.dp.Command.Sample.drawer;

import com.test.dp.Command.Sample.command.Command;
import java.awt.Point;

//表示“绘制一个点的命令”的类
public class DrawCommand implements Command {
    // 绘制对象
    protected Drawable drawable;
    // 绘制位置
    private Point position;
    // 构造函数
    public DrawCommand(Drawable drawable, Point position) {
        this.drawable = drawable;
        this.position = position;
    }
    // 执行
    public void execute() {
        drawable.draw(position.x, position.y);
    }
}
Drawable.java

package com.test.dp.Command.Sample.drawer;

//表示“绘制对象”的接口
public interface Drawable {
    public abstract void draw(int x, int y);
}
DrawCanvas.java

package com.test.dp.Command.Sample.drawer;

import com.test.dp.Command.Sample.command.*;

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

//实现“绘制对象”的类
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 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);
    }
}
Main.java

package com.test.dp.Command.Sample;

import com.test.dp.Command.Sample.command.*;
import com.test.dp.Command.Sample.drawer.*;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

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();
    }

    // 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 Main("Command Pattern Sample");
    }
}
执行结果:


总结:

应用实例:struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的 Command。

优点:1、降低了系统耦合度。2、新的命令可以很容易添加到系统中去。

缺点:使用命令模式可能会导致某些系统有过多的具体命令类。

使用场景:认为是命令的地方都可以使用命令模式,比如:1、GUI 中每一个按钮都是一条命令。2、模拟 CMD。

注意事项:系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,也可以考虑使用命令模式,见命令模式的扩展。


设计模式 —— 命令模式(Command Pattern)

命令模式(Command Pattern)概念: 概述:在软件设计中,我们经常会遇到某些对象发送请求,然后某些对象接受请求后执行,但发送请求的对象可能并不知道接受请求的对象是谁,执行的是什么动作。...
  • wwh578867817
  • wwh578867817
  • 2016年05月29日 18:34
  • 1233

设计模式(行为型)之命令模式(Command Pattern)

在软件开发中,我们经常需要向某些对象发送请求(调用其中的某个或某些方法),但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,此时,我们特别希望能够以一种松耦合的方式来设计软件,使得请求发送者与...
  • yanbober
  • yanbober
  • 2015年05月05日 11:49
  • 3165

设计模式之命令模式---Command Pattern

模式的定义命令模式是一个高内聚的模式,定义如下:Encapsulate a request as an object,thereby letting you parameterize clients ...
  • hfreeman2008
  • hfreeman2008
  • 2016年08月06日 10:37
  • 1582

设计模式 - 命令模式(command pattern) 撤销(undo) 详解

命令模式(command pattern) 撤销(undo) 详解本文地址: http://blog.csdn.net/caroline_wendy参考命令模式: http://blog.csdn.n...
  • u012515223
  • u012515223
  • 2014年06月16日 19:43
  • 3052

Unity游戏设计模式(一)命令模式(Command Pattern)

我想大部分的新人跟我一样刚开始学习Unity的时候,控制人物行的写法是这样的。 using UnityEngine; using System.Collections; public class ...
  • RinKas
  • RinKas
  • 2016年09月29日 10:46
  • 1871

命令模式(Command Pattern)(一):命令模式介绍

一、意图              将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。 二、适用性 ...
  • jialinqiang
  • jialinqiang
  • 2013年05月18日 23:16
  • 2904

Java开发中的23种设计模式详解----命令模式(Command)

命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。这个过程好在,三者相互解耦,任何一方都不用去依赖其...
  • sjyttkl
  • sjyttkl
  • 2017年06月21日 12:23
  • 935

浅谈JAVA设计模式之——命令模式(Command)

一、概述 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。 二、适用性 1.抽象出待执行的动作以参数化某对象。 2.在不同的时刻指...
  • l1028386804
  • l1028386804
  • 2015年05月08日 00:22
  • 4071

设计模式实例——基于命令模式的事件处理框架

在软件开发中,我们经常会遇到很多难以维护和修改的系统,一个不易于扩展的系统会很大程序的增加维护成本和出错率,所以我们在程序设计的时候一定要做一个易于扩展和维护的架构。今天我们就基于命令模式来做一个事件...
  • jakelylll
  • jakelylll
  • 2016年10月21日 09:38
  • 270

设计模式十五(命令模式,python语言实现)

基本原理请参考相应书籍,这里直接给实例     被控对象是机器人Robot,人(Client),通过控制器(controller)编程,给机器人发送指令。 Comand是指令的父类,具体指令有...
  • hitzjm
  • hitzjm
  • 2012年12月13日 09:16
  • 1394
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式(二十二)-命令模式(Command Pattern)——命令也是类
举报原因:
原因补充:

(最多只允许输入30个字)