首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java设计模式之命令模式

Java设计模式之命令模式

作者头像
shaoshaossm
发布于 2022-12-27 06:34:19
发布于 2022-12-27 06:34:19
41400
代码可运行
举报
文章被收录于专栏:Java啊Java啊
运行总次数:0
代码可运行

基本概念

命令模式使得请求发送者请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦。 在命令模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求,同时命令模式也支持可撤销的操作。 通俗易懂的理解:将军发布命令,士兵去执行。其中有几个角色:将军(命令发布者)、士兵(命令的具体执行者)、命令(连接将军和士兵)。

  • Invoker :是调用者角色
  • Command: 是命令角色,需要执行的所有命令都在这里,可以是接口或抽象类
  • Receiver: 接受者角色,知道如何实施和执行一个请求相关的操作
  • ConcreteCommand: 将一个接受者对象与一个动作绑定,调用接受者相应的操作,实现execute

案例

智能生活项目需求:我们买了一套智能家电,与照明灯、风扇、冰箱、洗衣机,我们只要在手机上安装一个app就可以控制这些家电工作。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface Command {
    //执行动作(操作)
    void execute();

    //撤销动作(操作)
    void undo();
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 没有任何命令,即空执行: 用于初始化每个按钮, 当调用空命令时,对象什么都不做
 * 其实,这样是一种设计模式, 可以省掉对空判断
 */
public class NoCommand implements Command {
    @Override
    public void execute() {

    }

    @Override
    public void undo() {

    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class LightReceiver {
    void on() {
        System.out.println("电灯打开了");
    }
    void off() {
        System.out.println("电灯关闭了");
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class LightOnCommand implements Command {
    LightReceiver lightReceiver;

    public LightOnCommand(LightReceiver lightReceiver) {
        this.lightReceiver = lightReceiver;
    }

    @Override
    public void execute() {
        lightReceiver.on();
    }

    @Override
    public void undo() {
        lightReceiver.off();
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class LightOffCommand implements Command {
    LightReceiver  lightReceiver;

    public LightOffCommand(LightReceiver lightReceiver) {
        this.lightReceiver = lightReceiver;
    }

    @Override
    public void execute() {
        lightReceiver.off();
    }

    @Override
    public void undo() {
        lightReceiver.on();
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class TVReceiver {

    public void on() {
        System.out.println(" 电视机打开了.. ");
    }

    public void off() {
        System.out.println(" 电视机关闭了.. ");
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class TVOnCommand implements Command {

    // 聚合TVReceiver

    TVReceiver tv;

    // 构造器
    public TVOnCommand(TVReceiver tv) {
        super();
        this.tv = tv;
    }

    @Override
    public void execute() {
        // 调用接收者的方法
        tv.on();
    }

    @Override
    public void undo() {
        // 调用接收者的方法
        tv.off();
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class TVOffCommand implements Command {

    // 聚合TVReceiver

    TVReceiver tv;

    // 构造器
    public TVOffCommand(TVReceiver tv) {
        super();
        this.tv = tv;
    }

    @Override
    public void execute() {

        // 调用接收者的方法
        tv.off();
    }

    @Override
    public void undo() {

        // 调用接收者的方法
        tv.on();
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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();
        }
    }

    // 给我们的按钮设置你需要的命令
    public void setCommand(int no, Command onCommand, Command offCommand) {
        onCommands[no] = onCommand;
        offCommands[no] = offCommand;
    }

    // 按下开按钮
    public void onButtonWasPushed(int no) { // no 0
        // 找到你按下的开的按钮, 并调用对应方法
        onCommands[no].execute();
        // 记录这次的操作,用于撤销
        undoCommand = onCommands[no];

    }

    // 按下关按钮
    public void offButtonWasPushed(int no) { // no 0
        // 找到你按下的关的按钮, 并调用对应方法
        offCommands[no].execute();
        // 记录这次的操作,用于撤销
        undoCommand = offCommands[no];

    }

    // 按下撤销按钮
    public void undoButtonWasPushed() {
        undoCommand.undo();
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        //使用命令设计模式,完成通过遥控器,对电灯的操作

        //创建电灯的对象(接受者)
        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();

    }

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
--------按下灯的开按钮-----------
电灯打开了
--------按下灯的关按钮-----------
电灯关闭了
--------按下撤销按钮-----------
电灯打开了
=========使用遥控器操作电视机==========
--------按下电视机的开按钮-----------
 电视机打开了.. 
--------按下电视机的关按钮-----------
 电视机关闭了.. 
--------按下撤销按钮-----------
 电视机打开了.. 

命令模式的注意事项和细节

  • 将发起请求的对象与执行请求的对象解耦。发起请求的对象是调用者,调用者只要调用命令对象的execute()方法就可以让接收者工作,而不必知道具体的接收者对象是谁、是如何实现的,命令对象会负责让接收者执行请求的动作,也就是说:”请求发起者”和“请求执行者”之间的解耦是通过命令对象实现的,命令对象起到了纽带桥梁的作用。
  • 容易设计一个命令队列。只要把命令对象放到列队,就可以多线程的执行命令
  • 容易实现对请求的撤销和重做
  • 命令模式不足:可能导致某些系统有过多的具体命令类,增加了系统的复杂度,这点在在使用的时候要注意
  • 空命令也是一种设计模式,它为我们省去了判空的操作。在上面的实例中,如果没有用空命令,我们每按下一个按键都要判空,这给我们编码带来一定的麻烦。
  • 命令模式经典的应用场景:界面的一个按钮都是一条命令、模拟CMD(DOS命令)订单的撤销/恢复、触发-反馈机制
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-05-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
ssh访问控制,多次失败登录即封掉IP,防止暴力破解
近期一直发现站内的流量和IP不太正常,读取/var/log/secure 很多失败的登录信息!必须要整个方法整死他们,虽然我已经把ssh port修改为了XXX(能告诉你吗?)!但是攻击还是不断,随即请教了铭哥大神。由于担心没有测试机,直接线上操作把自己也加入black list就不好了。找了很多资料,最终也成功了。分享给大家! 一、系统:Centos6.9 64位 二、方法:读取/var/log/secure,查找关键字 Failed,(#cat /var/log/secure | grep Failed
老七Linux
2018/05/09
5.6K1
SSH访问控制,多次失败登录即封掉IP,防止暴力破解
二、方法:读取/var/log/secure,查找关键字 Failed,例如(注:文中的IP地址特意做了删减):
星哥玩云
2022/07/03
1.7K0
Linux---CentOS-Ubuntu防爆破SSH脚本
CentOS 7方式 黑名单IP touch /etc/black.txt SSH 防爆破脚本 vim /etc/secure_ssh.sh #!/bin/bash cat /var/log/secure|awk '/Failed/{print $(NF-3)}'|sort|uniq -c|awk '{print $2"="$1;}' > /etc/black.txt for i in `cat /etc/black.txt` do IP=`echo $i |awk -
院长技术
2021/02/19
1.3K0
CentOS7防ssh爆破脚本
说明: 当输入三次密码错误时,ip将记录到/etc/black.txt文件,自动将ip添加到/etc/hosts.deny文件里禁止登录,如取消限制,修改两个文件,删除指定ip即可。
院长技术
2021/02/19
1.3K0
ssh访问控制,阻断异常IP,防止暴力破解
由于业务需要将Linux服务器映射到公网访问,SSH 端口已经修改,但还是发现有很多IP进行暴力破解,尝试将异常IP阻止非法访问,实现方式①SSH黑名单 ②Firewalld防火墙添加drop规则;
Kevin song
2021/11/30
1.7K0
ssh访问控制,阻断异常IP,防止暴力破解
防攻击可以增加IP白名单/etc/hosts.allow和黑名单/etc/hosts.deny
防攻击可以增加IP白名单/etc/hosts.allow和黑名单/etc/hosts.deny
拓荒者
2019/03/11
4.6K0
自动禁止攻击IP登陆SSH,保护服务器安全
当你拥有一台服务器并且可以远程ssh登陆后,你会发现有很多恶意扫描工具骚扰你的服务器。最好的方法就是更换SSH登陆的端口号并且定时修改。但是仅仅想禁止某些IP登陆呢?
zhangheng
2020/04/29
2.1K0
Linux的ssh被爆破的应急处理!
作者站在ICT项目集成角度,不定期更新ICT项目集成类文章,技术方向涉及数通、安防,安全、云计算等;管理方向涉及项目管理,经验分享,IT新闻等。致力于普及时下最新的、最实在、最艳的ICT项目集成干货,阿祥志愿和您共同成长。
ICT系统集成阿祥
2025/06/24
2860
Linux的ssh被爆破的应急处理!
shell 脚本监控攻击IP禁止登录服务器
# 编写脚本 vi ipssh.sh #! /bin/bash cat /var/log/secure | awk '/Failed/{print $(NF-3)}'|sort|uniq -c|awk '{print $1"="$2;}' > /usr/local/bin/black.list # 查看文件 # awk '/Failed/{print $0}' 字段处理,符号 / / 指定包含 Failed 单词的行,打印 $0 所有列 # 此处是指
eisc
2021/01/13
1.9K0
shell 脚本监控攻击IP禁止登录服务器
Linux 禁止用户或 IP通过 SSH 登录
在 /etc/ssh/sshd_config 配置文件中设置 AllowUsers 选项,(配置完成需要重启 SSHD 服务)格式如下:
拓荒者
2019/03/15
9.3K0
Linux 禁止用户或 IP通过 SSH 登录
DenyHosts 阻止SSH暴力攻击
首先sshd服务可以说是linux服务器一个至关重要的服务,如果被暴力破解成功,就直接可以拿到服务器的控制权了,在这里有两种解决方案,第一种是直接生成秘钥然后配置ssh服务无密码登录,然后在配置文件中禁用用户使用密码登录,这种方案相对来说比较安全,但配置有点麻烦啊......
胡齐
2019/09/23
2.1K0
DenyHosts 阻止SSH暴力攻击
系统安全之SSH入侵的检测与响应
作为系列文章的第一篇https://www.freebuf.com/es/193557.html 介绍了攻防系统的整个环境和搭建方法,按照这篇文章应该是可以把整个环境搭建完毕的.。在这篇文章中还介绍到了课程大纲包含主机安全、web安全、后门/木马等等,下面就让我们开始我们的实验课程。
FB客服
2019/03/08
3.9K0
系统安全之SSH入侵的检测与响应
linux使用DenyHosts阻止SSH服务器攻击(暴力破解)
DenyHosts 是一个开源且免费的基于日志的入侵防御安全程序. 它旨在通过阻止发起方来监视和分析 SSH 服务器日志中的无效登录尝试、基于字典的攻击和暴力攻击。IP 通过添加条目到地址 /etc/hosts.deny 服务器上的文件,并防止 IP 地址进行任何进一步的此类登录尝试。 如何在Linux中安装DenyHosts 默认情况下 DenyHosts Linux 系统中不包含该工具,使用以下yum 命令安装软件包。 # yum install -y denyhosts denyhosts配置文件说
入门笔记
2022/06/02
9270
SSH 操作实践指南
那么,以后每次在电脑上使用 SSH 论证的时候,都会提示你输入秘钥密码,非常麻烦。
雪梦科技
2020/05/11
1.6K0
Lniux服务器安全访问控制
/etc/hosts.deny *脚本 /root/SSH_Deny_Rule.sh
以谁为师
2019/05/28
1.4K0
掌握Linux安全,SSH限制IP登录绕不开这3种方法!
为了加强集团服务器的安全性,近期启用了堡垒机,同时就需要对所有业务服务器的ssh进行访问限制,仅允许指定IP访问(堡垒机),其他IP来源则不允许放行。
ICT系统集成阿祥
2024/12/03
1.1K0
掌握Linux安全,SSH限制IP登录绕不开这3种方法!
kex_exchange_identification: read: Connection reset by peer
使用SSH客户端登录Linux实例提示“ssh_exchange_identification: read: Connection reset by peer”错误怎么办?
对你无可奈何
2023/07/08
6.4K0
云服务器上ssh服务安全加固
今天到一个朋友的创业公司进行技术交流,交流过程中,朋友提到他在阿里云上买的linux服务器上ssh服务经常被人暴力破解。我感觉很奇怪,一般来说ssh服务经过简单设置是很安全的,怎么可能会出现这种情况呢。进一步交流才知道他们购买linux服务器后,连一些基本的安全措施都没做。原来并不是所有人都知道放在公网上的服务器是要进行简单的安全加固的。下面把我这些年使用linux时对ssh服务的安全加固步骤写下来,以便其它人参考。(以下的命令脚本基于CentOS6,其它发行版类似) 使用普通用户密钥文件登录 直接使用ro
jeremyxu
2018/05/10
7.7K0
CentOS服务器安全防护实例
可以限制瞬间连接数过大的恶意IP(比如web应用防护,但不适用于LVS+Keepalived集群环境) 防护指令如下
用户1685462
2021/07/17
1.1K0
防暴力激活成功教程密码的脚本「建议收藏」
前几天,使用Azure上的云主机突然cpu使用率上升了很多,发现日志文件/var/log/auth.log(ubuntu)或者/var/log/secure(centos),存在好多尝试激活成功教程用户密码的现象,如下脚本通过获取到日志文件的IP地址,加入到/etc/hosts.deny文件中,拒绝该IP地址的尝试登陆服务器。
全栈程序员站长
2022/09/23
3700
推荐阅读
相关推荐
ssh访问控制,多次失败登录即封掉IP,防止暴力破解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档