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

news2025/5/11 6:01:46

二十二、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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2298849.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker容器部署jar应用导入文件时候报缺少字体错误解决

如题,在导入文件时候报错如下: Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager 经查是缺少对应字体,解决办法有两张: 第一种:…

npm安装时无法访问github域名的解决方法

个人博客地址:npm安装时无法访问github域名的解决方法 | 一张假钞的真实世界 今天在用npm install的时候出现了github项目访问不了的异常: npm ERR! Error while executing: npm ERR! /bin/git ls-remote -h -t https://github.com/nhn/raphael.git np…

APP端弱网模拟与网络测试:如何确保应用在各种网络环境下稳定运行

随着智能手机的普及,APP的网络性能成为用户体验的关键因素之一。尤其是在弱网环境下,应用的表现可能严重影响用户的满意度。因此,APP端的网络测试,尤其是弱网模拟,成为了提升产品质量和用户体验的重要环节。 当前APP网…

从 ClickHouse 到 Apache Doris:在网易云音乐日增万亿日志数据场景下的落地

导读:日志数据已成为企业洞察系统状态、监控网络安全及分析业务动态的宝贵资源。网易云音乐引入 Apache Doris 作为日志库新方案,替换了 ClickHouse。解决了 ClickHouse 运维复杂、不支持倒排索引的问题。目前已经稳定运行 3 个季度,规模达到…

BFS 走迷宫

#include<bits/stdc.h> using namespace std; int a[100][100],v[100][100];//访问数组 n,m<100 struct point {int x;int y;int step; }; queue<point> r;//申请队列 int dx[4]{0,1,0,-1};//四个方向 右下左上 int dy[4]{1,0,-1,0}; int main() { /* 5 4 1 …

计算机毕业设计SpringBoot+Vue.js医院住院管理系统(源码+lw文档+PPT+讲解视频)

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

MongoDB 7 分片副本集升级方案详解(下)

#作者&#xff1a;任少近 文章目录 1.4 分片升级1.5 升级shard11.6 升级shard2,shard31.7 升级mongos1.8重新启用负载均衡器1.9 推荐MongoDB Compass来验证数据 2 注意事项&#xff1a; 1.4 分片升级 使用“滚动”升级从 MongoDB 7.0 升级到 8.0&#xff0c;即在其他成员可用…

【含开题报告+文档+PPT+源码】基于spring boot的固定资产管理系统

开题报告 本研究论文提出了一种基于SpringBoot框架构建的全面且高效的固定资产管理系统&#xff0c;旨在优化企业内部的固定资产全生命周期管理流程。该系统集成了员工权限管理、业务流程处理及数据分析于一体&#xff0c;实现了员工便捷的登录注册功能&#xff0c;并通过安全…

Unity嵌入到Winform

Unity嵌入到Winform Winform工程&#x1f308;

Svelte 最新中文文档翻译(8)—— @html、@const、@debug 模板语法

前言 Svelte&#xff0c;一个非常“有趣”、用起来“很爽”的前端框架。从 Svelte 诞生之初&#xff0c;就备受开发者的喜爱&#xff0c;根据统计&#xff0c;从 2019 年到 2024 年&#xff0c;连续 6 年一直是开发者最感兴趣的前端框架 No.1&#xff1a; Svelte 以其独特的编…

Qt Designer菜鸟使用教程(实现一个本地英文翻译软件)

1 安装Qt Designer 安装这个包的时候会自带安装 Qt Designer, 安装目录为python的安装根目录的 Lib/site-packages/qt5_applications/Qt/bin 目录下。 pip install pyqt5-tools2 新建窗体 2.1 新建主窗体 创建之后如下图&#xff1a; 设置主窗口大小&#xff1a; 设置窗…

CPT205 计算机图形学 OpenGL 3D实践(CW2)

文章目录 1. 介绍2. 设计3. 准备阶段4. 角色构建5. 场景构建6. 交互部分6.1 键盘交互6.2 鼠标交互6.3 鼠标点击出多级菜单进行交互 7. 缺点与问题7.1 程序bug7.2 游戏乐趣不足7.3 画面不够好看 8. 完整代码 1. 介绍 前面已经分享过了关于CPT205的CW1的2D作业&#xff0c;这次C…

利用蓝耘智算平台深度搭建deepseek R1模型,进行深度机器学习

大佬请阅读 前言关于DeepSeek 的显著优点卓越的性能表现低廉的训练成本广泛的应用场景开放的开源策略 DeepSeek 与其他 AI 对比什么是蓝耘智算平台为什么使用蓝耘智算平台搭建我们的deepseek如何使用蓝耘 GPU 智算云平台搭建我们的R1模型并成功进行调用测试11. AVL树节点结构2.…

传输层协议TCP (上)

文章目录 前言TCP报文格式TCP连接管理连接建立与中止三次握手三次握手的状态变化为什么是三次握手 四次挥手四次挥手的状态变化FIN_WAIT_2 状态可能导致连接长时间不释放的问题TIME_WAIT状态作用 复位报文段非法连接请求其他异常情况 半打开连接同时握手同时关闭 参考资料 前言…

深度学习框架探秘|Keras:深度学习的魔法钥匙

一、引言&#xff1a;深度学习浪潮中的 Keras 前面的文章我们探秘了深度学习框架中的两大明星框架 —— TensorFlow 和 PyTorch 以及 两大框架的对比 在深度学习的众多框架中&#xff0c;还有一款框架备受开发者们的喜爱 —— Keras 。它就像是一位贴心的助手&#xff0c;为我…

2.11学习

misc buu-荷兰宽带泄露 下载附件得到了一个后缀为.bin的文件 是宽带数据文件&#xff0c;用RouterPassView工具进行查看。大多数现代路由器都可以让您备份一个文件路由器的配置文件&#xff0c;然后在需要的时候从文件中恢复配置。路由器的备份文件通常包含了像您的ISP的用户…

Python 调用 DeepSeek API 案例详细教程

本案例为以 Python 为例的调用 DeepSeek API 的小白入门级详细教程 步骤 先注册并登录 DeepSeek 官网&#xff1a;https://www.deepseek.com/ 手机号验证码注册或登录即可 创建 API KEY 注意保存&#xff0c;写代码时必须提供的 打开 Pycharm 创建工程 并安装 OpenAI 库编写代…

C++ Primer 函数基础

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

【SVN基础】

软件&#xff1a;ToritoiseSVN 代码版本回退&#xff1a;回退到上一个版本 问题&#xff1a;SVN版本已经提交了版本1和版本2&#xff0c;现在发现不需要版本2的内容&#xff0c;需要回退到版本1然后继续开发。 如图SVN版本已经提交到了107版本&#xff0c;那么本地仓库也已经…

kron积计算mask类别矩阵

文章目录 1. 生成类别矩阵如下2. pytorch 代码3. 循环移动矩阵 1. 生成类别矩阵如下 2. pytorch 代码 import torch import torch.nn as nn import torch.nn.functional as Ftorch.set_printoptions(precision3, sci_modeFalse)if __name__ "__main__":run_code 0…