当前位置: 首页 > news >正文

《图解设计模式》笔记(十)用类来表现

二十二、Command模式:命令也是类

一个类调用某方法,虽然调用结果会反映在对象的状态中,但不会留下工作的历史记录。
若有一个类表示“请进行这项工作”的“命令”,每一项想做的工作就不再是“方法的调用”这种动态处理了,而是一个表示命令的类的实例,即可以用“物”来表示。
想管理工作的历史记录,只需管理这些实例的集合即可,且还可以随时再次执行过去的命令,或是将多个过去的命令整合为一个新命令并执行。
在设计模式中,称这样的“命令”为Command模式。
Command有时也被称为事件(event)。它与“事件驱动编程”中的“事件”是一样的意思。当发生点击鼠标、按下键盘按键等事件时,可以先将这些事件作成实例,然后按照发生顺序放入队列中。接着,再依次去处理它们。

示例程序
是一个画图软件,它的功能很简单,即用户拖动鼠标时程序会绘制出红色圆点,点击clear按钮后会清除所有的圆点。
用户每拖动一次鼠标,应用程序都会为“在这个位置画一个点”这条命令生成一个DrawCommand类的实例。
只要保存了这条命令,以后有需要时就可以重新绘制。

示例程序的运行结果

在这里插入图片描述

示例程序类图

在这里插入图片描述

Command

package command;

public interface Command {
   
    public abstract void execute();
}

MacroCommand

package command;

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

public class MacroCommand implements Command {
   
    // 命令的集合
    // 虽然这里也可以使用java.util.ArrayList类型,但为了能轻松地实现undo方法,还是决定使用java.util.Stack类型
    private Stack commands = new Stack();

    // execute方法应该进行什么处理呢?
    // 既然要运行多条命令,那么只调用commands字段中各个实例的execute方法不就可以了吗?这样,就可以将MacroCommand自己保存的所有 Command全部执行一遍。
    // 不过,如果while循环中要执行的 Command又是另外一个MacroCommand类的实例,该实例中的execute方法也是会被调用的。因此,最后的结果就是所有的Command全部都会被执行。
    // 执行
    public void execute() {
   
        Iterator it = commands.iterator();
        while (it.hasNext()) {
   
            ((Command)it.next()).execute();
        }
    }
    // 添加命令
    public void append(Command cmd) {
   
        // 防止不小心将自己(this)添加进去,否则execute方法将会陷入死循环
        if (cmd != this) {
   
            // java.util.Stack类的push方法,它会将元素添加至java.util.Stack类的实例的末尾
            commands.push(cmd);
        }
    }
    // 删除最后一条命令
    public void undo() {
   
        if (!commands.empty()) {
   
            // java.util.Stack类的pop方法,它会将push方法添加的最后一条命令取出来,并从Stack类的实例中移除
            commands.pop();
        }
    }
    // 删除所有命令
    public void clear() {
   
        commands.clear();
    }
}

DrawCommand

package drawer;

import command.Command;
import java.awt.Point;

public class DrawCommand implements Command {
   
    // 绘制对象
    protected Drawable drawable;
    // 绘制位置
    private Point position;
    // 构造函数
    // 接收两个参数:Drawable的实现类,Point类,分别保存在drawable字段和position字段中。它的作用是生成“在这个位置绘制点”的命令。
    public DrawCommand(Drawable drawable, Point position) {
   
        this.drawable = drawable;
        this.position = position;
    }
    // 执行
    public void execute() {
   
        drawable.draw(position.x, position.y);
    }
}

Drawable

package drawer;

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

DrawCanvas

package drawer;

import command.*;

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

public class DrawCanvas extends Canvas implements

相关文章:

  • 【HDFS】addInternalPBProtocol、setProtocolEngine和registerProtocolAndImpl
  • java-LinkedList源码详解
  • 常见面试提问
  • 【Java八股文】06-MySQL面试篇
  • MySQL 支持的事务隔离级别
  • C++之2048小游戏 第二期
  • PHP 基础介绍
  • 使用Nuitka工具打包Python程序成exe
  • 【Java八股文】01-Java基础面试篇
  • 猜数字小游戏
  • 使用Hexo部署NexT主体网站
  • SQL SERVER的PARTITION BY应用场景
  • C# CountdownEvent 类 使用详解
  • 认识网络安全
  • 【css】width:100%;padding:20px;造成超出100%宽度的解决办法 - box-sizing的使用方法 - CSS布局
  • Android Studio:RxBus结合ICompositeSubscription使用
  • YOLO数据标注——LabelImg
  • PMP--冲刺--流程图
  • vue3+element-plus中的el-table表头和el-table-column内容全部一行显示完整(hook函数)
  • 【第3章:卷积神经网络(CNN)——3.8 迁移学习与微调策略】
  • 山大齐鲁医院通报“子宫肌瘤论文现男性患者”:存在学术不端
  • 五一上海楼市热闹开局:售楼处全员到岗,热门楼盘连续触发积分
  • 9金收官!跳水世界杯总决赛朱子锋、程子龙包揽男子10米台冠亚军
  • “五一”假期余额不足两天,多地景点已约满、限流
  • 巴菲特股东大会精华版:批评拿贸易当武器,宣布年底交班
  • 几天洗一次头发最好?终于有答案了...