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

【设计模式——学习笔记】23种设计模式——命令模式Command(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录

  • 案例引入
  • 介绍
    • 基础介绍
    • 登场角色
  • 案例实现
    • 案例一
      • 实现
    • 案例二
      • 介绍
      • 实现
      • 拓展
  • 命令模式在JdbcTemplate源码中的应用
  • 总结
  • 文章说明

案例引入

  • 有一套智能家电,其中有照明灯、风扇、冰箱、洗衣机,这些智能家电来自不同的厂家,我们不想针对每一种家电都安装一个手机App来分别控制,希望只要一个app就可以控制全部智能家电
  • 要实现一个app控制所有智能家电的需要,则每个智能家电厂家都要提供一个统一的接口给app调用,这样可以考虑使用命令模式
  • 命令模式可将“动作的请求者”从“动作的执行者”对象中解耦出来
  • 在我们的例子中,动作的请求者是手机app,动作的执行者是每个厂商的一个家电产品

介绍

基础介绍

  • 一个类在进行工作时会调用自己或是其他类的方法,虽然调用结果会反映在对象的状态中,但并不会留下工作的历史记录。这时,如果有一个类用来表示“请示进行这项工作”的“命令”就会方便很多。每一项想做的工作就不再是“方法的调用”这种动态处理了,而是一个表示命令的类的实例,即可以用“物”来表示。要想管理工作的历史记录,只需管理这些实例的集合即可,而且还可以随时再次执行过去的命令,或是将多个过去的命令整合为一个新命令并执行。这样的模式称为命令模式
  • 命令模式使得请求发送者请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦,我们只需在程序运行时指定具体的请求接收者即可
  • 在命令模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求(即命令),同时命令模式也支持可撤销的操作
  • 通俗易懂的理解:将军发布命令,士兵去执行(将军只需要发布一个进攻命令即可,不需要指定哪位士兵要做什么,士兵就会各司其职)。其中有几个角色:将军(命令发布者)、士兵(命令的具体执行者)、命令(连接将军和士兵)

登场角色

  • Command(命令):负责定义命令的接口(API)
  • ConcreteCommand(具体的命令):ConcreteCommand角色负责实现在Command角色中定义的接口(API)。聚合接收者,将一个接收者对象与一个动作绑定,调用接收者相应的操作来实现execute
  • Receiver(接收者):Receiver角色是执行命令的对象,知道如何实施和执行一个请求对应的操作
  • Client(请求者):Client角色负责生成ConcreteCommand角色并分配Receiver角色
  • Invoker(发动者):调用在Command 角色中定义的接口(API)

在这里插入图片描述

案例实现

案例一

在这里插入图片描述

实现

【Commond】

package com.atguigu.command;/*** 创建命令接口*/
public interface Command {/*** 执行动作(操作)*/public void execute();/*** 撤销动作(操作)*/public void undo();
}

【电灯命令执行者】

package com.atguigu.command;/*** 真正执行者*/
public class LightReceiver {public void on() {System.out.println(" 电灯打开了.. ");}public void off() {System.out.println(" 电灯关闭了.. ");}
}

【关灯命令】

package com.atguigu.command;public class LightOffCommand implements Command {/*** 聚合LightReceiver*/LightReceiver light;/*** 构造器* @param light*/public LightOffCommand(LightReceiver light) {super();this.light = light;}@Overridepublic void execute() {// 调用接收者的方法light.off();}@Overridepublic void undo() {// 调用接收者的方法light.on();}
}

【开灯命令】

package com.atguigu.command;public class LightOnCommand implements Command {/*** 聚合LightReceiver*/LightReceiver light;/*** 构造器** @param light*/public LightOnCommand(LightReceiver light) {super();this.light = light;}@Overridepublic void execute() {//调用接收者的方法light.on();}@Overridepublic void undo() {//调用接收者的方法light.off();}}

【电视命令执行者】

package com.atguigu.command;public class TVReceiver {public void on() {System.out.println(" 电视机打开了.. ");}public void off() {System.out.println(" 电视机关闭了.. ");}
}

【关电视命令】

package com.atguigu.command;public class TVOffCommand implements Command {/*** 聚合TVReceiver*/TVReceiver tv;/*** 构造器** @param tv*/public TVOffCommand(TVReceiver tv) {super();this.tv = tv;}@Overridepublic void execute() {// 调用接收者的方法tv.off();}@Overridepublic void undo() {// 调用接收者的方法tv.on();}
}

【开电视命令】

package com.atguigu.command;public class TVOnCommand implements Command {/*** 聚合TVReceiver*/TVReceiver tv;/*** 构造器** @param tv*/public TVOnCommand(TVReceiver tv) {super();this.tv = tv;}@Overridepublic void execute() {// 调用接收者的方法tv.on();}@Overridepublic void undo() {// 调用接收者的方法tv.off();}
}

【空命令】

package com.atguigu.command;/*** 没有任何命令,即空执行: 用于初始化每个按钮, 当调用空命令时,对象什么都不做* 其实,这样是一种设计模式, 可以省掉对空判断* @author Administrator**/
public class NoCommand implements Command {@Overridepublic void execute() {}@Overridepublic void undo() {}} 

【遥控器】

package com.atguigu.command;public class RemoteController {/*** 开 按钮的命令数组*/Command[] onCommands;Command[] offCommands;/*** 执行撤销的命令,必须要记住上一次执行的命令对应的撤销命令才能撤销*/Command undoCommand;/*** 构造器,完成对按钮初始化*/public RemoteController() {onCommands = new Command[5];offCommands = new Command[5];// 初始化五组命令,初始化为空命令for (int i = 0; i < 5; i++) {onCommands[i] = new NoCommand();offCommands[i] = new NoCommand();}}/*** 给我们的按钮设置你需要的命令** @param no 命令编号* @param onCommand* @param offCommand*/public void setCommand(int no, Command onCommand, Command offCommand) {onCommands[no] = onCommand;offCommands[no] = offCommand;}/*** 按下开按钮** @param no*/public void onButtonWasPushed(int no) {// 找到你按下的开的按钮, 并调用对应方法onCommands[no].execute();// 记录这次的操作,用于撤销undoCommand = onCommands[no];}/*** 按下开按钮** @param no*/public void offButtonWasPushed(int no) {// 找到你按下的关的按钮, 并调用对应方法offCommands[no].execute();// 记录这次的操作,用于撤销undoCommand = offCommands[no];}/*** 按下撤销按钮*/public void undoButtonWasPushed() {undoCommand.undo();}}

【客户端】

package com.atguigu.command;public class Client {public static void main(String[] args) {//使用命令设计模式,完成通过遥控器,对电灯的操作//创建电灯的对象(接受者)LightReceiver lightReceiver = new LightReceiver();//创建电灯相关的开关命令LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);//需要一个遥控器RemoteController remoteController = new RemoteController();//给我们的遥控器设置命令, 比如 no = 0 是电灯的开和关的操作remoteController.setCommand(0, lightOnCommand, lightOffCommand);System.out.println("--------按下灯的开按钮-----------");remoteController.onButtonWasPushed(0);System.out.println("--------按下灯的关按钮-----------");remoteController.offButtonWasPushed(0);System.out.println("--------按下撤销按钮-----------");remoteController.undoButtonWasPushed();System.out.println("=========使用遥控器操作电视机==========");TVReceiver tvReceiver = new TVReceiver();TVOffCommand tvOffCommand = new TVOffCommand(tvReceiver);TVOnCommand tvOnCommand = new TVOnCommand(tvReceiver);//给我们的遥控器设置命令, 比如 no = 1 是电视机的开和关的操作remoteController.setCommand(1, tvOnCommand, tvOffCommand);System.out.println("--------按下电视机的开按钮-----------");remoteController.onButtonWasPushed(1);System.out.println("--------按下电视机的关按钮-----------");remoteController.offButtonWasPushed(1);System.out.println("--------按下撤销按钮-----------");remoteController.undoButtonWasPushed();}}

【运行】

--------按下灯的开按钮-----------电灯打开了.. 
--------按下灯的关按钮-----------电灯关闭了.. 
--------按下撤销按钮-----------电灯打开了.. 
=========使用遥控器操作电视机==========
--------按下电视机的开按钮-----------电视机打开了.. 
--------按下电视机的关按钮-----------电视机关闭了.. 
--------按下撤销按钮-----------电视机打开了.. Process finished with exit code 0

案例二

介绍

这段示例程序是一个画图软件,它的功能很简单,即用户拖动鼠标时程序会绘制出红色圆点,点击 clear 按钮后会清除所有的圆点。

在这里插入图片描述

实现

在这里插入图片描述

【命令接口】

package com.atguigu.command.Sample.command;public interface Command {/*** 执行*/public abstract void execute();
}

【历史命令集:由多条命令整合成的命令】

如果保存这个实例,就可以永久保存历史数据

package com.atguigu.command.Sample.command;import java.util.Iterator;
import java.util.Stack;/*** 由多条命令整合成的命令*/
public class MacroCommand implements Command {/*** 存储命令的栈*/private Stack commands = new Stack();/*** 执行*/public void execute() {// 一次性执行一系列命令Iterator it = commands.iterator();while (it.hasNext()) {((Command) 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();}
}

【绘制点命令】

package com.atguigu.command.Sample.drawer;import com.atguigu.command.Sample.command.Command;
import java.awt.*;public class DrawCommand implements Command {/*** 绘制对象*/protected Drawable drawable;/*** 绘制位置 Point 是 java.awt 包的类,含有 (x,y) 坐标*/private Point position;/*** 构造函数** @param drawable* @param position*/public DrawCommand(Drawable drawable, Point position) {this.drawable = drawable;this.position = position;}/*** 执行*/public void execute() {drawable.draw(position.x, position.y);}
}

【绘制对象接口】

package com.atguigu.command.Sample.drawer;public interface Drawable {public abstract void draw(int x, int y);
}

【绘图类】

package com.atguigu.command.Sample.drawer;import com.atguigu.command.Sample.command.MacroCommand;import java.awt.*;/*** 继承Canvas*/
public class DrawCanvas extends Canvas implements Drawable {/*** 颜色*/private Color color = Color.red;/*** 要绘制的圆点的半径*/private int radius = 6;/*** 命令的历史记录*/private MacroCommand history;/*** 构造函数** @param width* @param height* @param history*/public DrawCanvas(int width, int height, MacroCommand history) {// 设置画布尺寸setSize(width, height);// 设置画布颜色setBackground(Color.white);this.history = history;}/*** 重新全部绘制* @param g   the specified Graphics context*/public void paint(Graphics g) {history.execute();}/*** 绘制* @param x* @param y*/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.atguigu.command.Sample;import com.atguigu.command.Sample.command.*;
import com.atguigu.command.Sample.drawer.*;import javax.swing.*;
import java.awt.event.*;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");/*** 构造函数* @param title*/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接口中的方法* @param e*/public void actionPerformed(ActionEvent e) {if (e.getSource() == clearButton) {// 清空历史命令history.clear();// 清空画布canvas.repaint();}}public void mouseMoved(MouseEvent e) {}/***  MouseMotionListener接口中的方法* @param e*/public void mouseDragged(MouseEvent e) {// 鼠标位置一改变,就创建绘制点命令放到命令集合中Command cmd = new DrawCommand(canvas, e.getPoint());// 执行绘制cmd.execute();history.append(cmd);}/***  WindowListener接口中的方法* @param e*/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");}
}

在这里插入图片描述

【运行】

在这里插入图片描述

拓展

如何示例程序中增加“设置颜色”的功能。

【颜色命令】

package com.atguigu.command.A1.drawer;import com.atguigu.command.A1.command.Command;import java.awt.*;public class ColorCommand implements Command {/*** 绘制对象*/protected Drawable drawable;/*** 颜色*/private Color color;/*** 构造函数** @param drawable* @param color*/public ColorCommand(Drawable drawable, Color color) {this.drawable = drawable;this.color = color;}/*** 执行* 设置画笔的颜色*/public void execute() {drawable.setColor(color);}
}

【主类】

package com.atguigu.command.A1;import com.atguigu.command.A1.command.Command;
import com.atguigu.command.A1.command.MacroCommand;
import com.atguigu.command.A1.drawer.ColorCommand;
import com.atguigu.command.A1.drawer.DrawCanvas;
import com.atguigu.command.A1.drawer.DrawCommand;import javax.swing.*;
import java.awt.*;
import java.awt.event.*;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");/*** 红色按钮*/private JButton redButton = new JButton("red");/*** 绿色按钮*/private JButton greenButton = new JButton("green");/*** 蓝色按钮*/private JButton blueButton = new JButton("blue");/*** 构造函数** @param title*/public Main(String title) {super(title);this.addWindowListener(this);canvas.addMouseMotionListener(this);clearButton.addActionListener(this);redButton.addActionListener(this);greenButton.addActionListener(this);blueButton.addActionListener(this);Box buttonBox = new Box(BoxLayout.X_AXIS);buttonBox.add(clearButton);buttonBox.add(redButton);buttonBox.add(greenButton);buttonBox.add(blueButton);Box mainBox = new Box(BoxLayout.Y_AXIS);mainBox.add(buttonBox);mainBox.add(canvas);getContentPane().add(mainBox);pack();show();}/*** ActionListener接口中的方法* 点击不同颜色的按钮,设置不同颜色画笔** @param e*/public void actionPerformed(ActionEvent e) {if (e.getSource() == clearButton) {history.clear();canvas.init();canvas.repaint();} else if (e.getSource() == redButton) {Command cmd = new ColorCommand(canvas, Color.red);history.append(cmd);cmd.execute();} else if (e.getSource() == greenButton) {Command cmd = new ColorCommand(canvas, Color.green);history.append(cmd);cmd.execute();} else if (e.getSource() == blueButton) {Command cmd = new ColorCommand(canvas, Color.blue);history.append(cmd);cmd.execute();}}/*** MouseMotionListener接口中的方法** @param e*/public void mouseMoved(MouseEvent e) {}public void mouseDragged(MouseEvent e) {Command cmd = new DrawCommand(canvas, e.getPoint());history.append(cmd);cmd.execute();}/*** WindowListener接口中的方法** @param e*/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");}
}

【运行】

在这里插入图片描述

命令模式在JdbcTemplate源码中的应用

应用模式和标准的命令模式有点区别,但是精髓是差不多的

在这里插入图片描述

在这里插入图片描述

还有其他的命令执行者

在这里插入图片描述

在这里插入图片描述

总结

【优点】

  • 发起请求的对象执行请求的对象解耦。发起请求的对象是调用者,调用者只要调用命令对象的execute()方法就可以让接收者工作,而不必知道具体的接收者对象是谁、是如何实现的。命令对象(就是具体的命令)会负责让接收者执行调用者请求的动作,也就是说:”请求发起者”和“请求执行者”之间的解耦是通过命令对象实现的,命令对象起到了纽带桥梁的作用
  • 命令模式容易设计一个命令队列。只要把命令对象放到队列,就可以多线程地执行命令。不仅如此,还容易将命令执行的历史纪录保存起来
  • 命令模式容易实现对请求的撤销和重做
  • 空命令也是一种设计模式,它为我们省去了判空的操作。在上面的实例中,如果没有用空命令,我们每按下一个按键都要判空,这给我们编码带来一定的麻烦(声明命令数组时,首先将数组的元素全部初始化为空命令)

【缺点】

  • 可能导致某些系统有过多的具体命令类,增加了系统的复杂度

文章说明

  • 本文章为本人学习尚硅谷的学习笔记,文章中大部分内容来源于尚硅谷视频(点击学习尚硅谷相关课程),也有部分内容来自于自己的思考,发布文章是想帮助其他学习的人更方便地整理自己的笔记或者直接通过文章学习相关知识,如有侵权请联系删除,最后对尚硅谷的优质课程表示感谢。
  • 本人还同步阅读《图解设计模式》书籍(图解设计模式/(日)结城浩著;杨文轩译–北京:人民邮电出版社,2017.1),进而综合两者的内容,让知识点更加全面

相关文章:

【设计模式——学习笔记】23种设计模式——命令模式Command(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录 案例引入介绍基础介绍登场角色 案例实现案例一实现 案例二介绍实现拓展 命令模式在JdbcTemplate源码中的应用总结文章说明 案例引入 有一套智能家电&#xff0c;其中有照明灯、风扇、冰箱、洗衣机&#xff0c;这些智能家电来自不同的厂家&#xff0c;我们不想针对每一…...

Rust中的高吞吐量流处理

本篇文章主要介绍了Rust中流处理的概念、方法和优化。作者不仅介绍了流处理的基本概念以及Rust中常用的流处理库&#xff0c;还使用这些库实现了一个流处理程序。 最后&#xff0c;作者介绍了如何通过测量空闲和阻塞时间来优化流处理程序的性能&#xff0c;并将这些内容同步至…...

探索编程世界的宝藏:程序员必掌握的20大算法

文章目录 1 引言2 冒泡排序算法&#xff1a;编程世界的排序魔法 &#x1f9d9;‍♀️&#x1f522;3 选择排序算法&#xff1a;排序世界的精确挑选器 &#x1f3af;&#x1f522;4 插入排序算法&#xff1a;排序世界的巧妙插珠者 ✨&#x1f522;5 快速排序算法&#xff1a;排序…...

Android NFC通信示例

前言 近距离无线通信 (NFC) 是一组近距离无线技术&#xff0c;通常只有在距离不超过 4 厘米时才能启动连接。借助 NFC&#xff0c;您可以在 NFC 标签与 Android 设备之间或者两台 Android 设备之间共享小型负载。 支持 NFC 的 Android 设备同时支持以下三种主要操作模式&…...

2023年08月IDE流行度最新排名

点击查看最新IDE流行度最新排名&#xff08;每月更新&#xff09; 2023年08月IDE流行度最新排名 顶级IDE排名是通过分析在谷歌上搜索IDE下载页面的频率而创建的 一个IDE被搜索的次数越多&#xff0c;这个IDE就被认为越受欢迎。原始数据来自谷歌Trends 如果您相信集体智慧&am…...

使用Beego和MySQL实现帖子和评论的应用,并进行接口测试(附源码和代码深度剖析)

文章目录 小项目介绍源码分析main.gorouter.gomodels/user.gomodels/Post.gomodels/comment.gocontrollers/post.gocontrollers/comment.go 接口测试测试增加帖子测试查看帖子测试增加评论测试查看评论 小项目介绍 经过对需求的分析&#xff0c;我增加了一些额外的东西&#x…...

物联网潜在的巨大价值在于大数据分析

物联网潜在的巨大价值在于大数据分析 从数据里去挖掘市场或者用户的精准需求。 往小的说&#xff0c;后台可以统计用户家里各各插座一年甚至更久的用电情况&#xff0c;这些数据也可以通过app或者小程序展现给用户。 用户可以很直观看到自己一年的用电情况&#xff0c;哪个家…...

SSL原理详解

SSL协议结构&#xff1a; SSL协议分为两层&#xff0c;下层为SSL记录协议&#xff0c;上层为SSL握手协议、SSL密码变化协议和SSL警告协议。 1.下层为SSL记录协议&#xff0c;主要作用是为高层协议提供基本的安全服务 建立在可靠的传输之上&#xff0c;负责对上层的数据进行分块…...

linux下的etc目录代表什么意思

在Linux系统中&#xff0c;/etc目录是一个非常重要的目录&#xff0c;它包含了系统的配置文件和相关的配置信息。下面是一些/etc目录中常见的文件和目录&#xff1a; 1. /etc/passwd&#xff1a;此文件包含了所有用户账户的信息&#xff0c;包括用户名、用户ID、用户所属的组I…...

iOS 两种方式设置状态栏

1、ios9.0以前设置状态栏字体颜色 ///白色 [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent]; ///黑色 [[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleDefault]; 会看到如下提示&#xff1a; setStatusBarSty…...

html5:webSocket 基础使用

一、理解 HTML5 WebSocket HTML5 WebSocket是一种新型的网络协议&#xff0c;它能够在客户端和服务器之间建立实时的双向通信通道&#xff0c;使得浏览器和服务器之间的数据传输更加高效、快速和可靠。相比传统的HTTP协议&#xff0c;WebSocket协议使用更少的网络开销&#xf…...

html学习10-----总结(完)

<!DOCTYPE html> <html><head><meta charset"utf-8"/><title>html总结</title></head><body><h1>HTML总结</h1><br/><h2>文本格式化</h2><hr/><p><b>粗体文本<…...

Spring使用P命名空间实现注入数值信息-----Spring框架

<?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:p"http://www.springframework.org/schema/p"x…...

windows环境下安装RabbitMQ

一、RabbitMq简介1.1消息队列中间件简介消息队列中间件是分布式系统中重要的组件&#xff0c;主要解决应用耦合&#xff0c;异步消息&#xff0c;流量削锋等问题实现高性能&#xff0c;高可用&#xff0c;可伸缩和最终一致性[架构] 使用较多的消息队列有 ActiveMQ(安全)&#x…...

Java源码规则引擎:jvs-rules决策流的自定义权限控制

规则引擎用于管理和执行业务规则。它提供了一个中央化的机制来定义、管理和执行业务规则&#xff0c;以便根据特定条件自动化决策和行为。规则引擎的核心概念是规则。规则由条件和动作组成。条件定义了规则适用的特定情况或规则触发的条件&#xff0c;而动作定义了规则满足时要…...

Python-字符串的世界

Python字符串的世界 在Python编程中&#xff0c;字符串&#xff08;String&#xff09;是一种非常重要的数据类型&#xff0c;用于表示文本信息。字符串可以包含字母、数字、特殊字符以及空格&#xff0c;它们在编程中被广泛用于文本处理、格式化输出、字符串匹配等各种场景。…...

使用上 Spring 的事件机制

本文主要是简单的讲述了Spring的事件机制&#xff0c;基本概念&#xff0c;讲述了事件机制的三要素事件、事件发布、事件监听器。如何实现一个事件机制&#xff0c;应用的场景&#xff0c;搭配Async注解实现异步的操作等等。希望对大家有所帮助。 Spring的事件机制的基本概念 …...

Linux安装QT

//进入qt安装包路径 cd qt安装包路径 //修改权限 sudo chmod x qt-opensource-linux-x64-5.14.2.run //运行qt安装包 sudo ./qt-opensource-linux-x64-5.14.2.run //安装编译器 sudo apt-get install gcc g //安装编译工具 sudo apt-get install build-essential //安装Op…...

如何用arduino uno主板播放自己想要的曲子。《我爱你中国》单片机版本。

目录 一.效果展示 二.基本原理 三.电路图 四.代码 一.效果展示 arduino播放《我爱你中国》 二.基本原理 利用arduino uno单片机实现对蜂鸣器振动频率的调节&#xff0c;基于PWM控制系统通过代码实现控制。 三.电路图 四.代码 //main.uno #define Buzzer 2int PotBuffer …...

redis入门2-命令

Redis的基本数据类型 redis的基本数据类型&#xff08;value&#xff09;: string,普通字符串 hash&#xff08;哈希&#xff09;,适合存储对象 list(列表),按照插入顺序排序&#xff0c;可以由重复的元素 set(无序集合)&#xff0c;没有重复的元素 sorted set(有序集合)&…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

GitHub 趋势日报 (2025年06月08日)

&#x1f4ca; 由 TrendForge 系统生成 | &#x1f310; https://trendforge.devlive.org/ &#x1f310; 本日报中的项目描述已自动翻译为中文 &#x1f4c8; 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...