设计模式——行为型模式之命令模式(你还在纠结事件监听体系到底怎么设计的吗?命令模式为你解答疑惑)


前言

设计模式是进行实际开发的基石,是前人不断总结试错得出的宝贵开发经验,也是开发人员之间相互理解共同设计的关键标准。学习设计模式能够帮助我们初学者更好理解结构化的开发流程,摆脱只会写一段代码而不能上升为一个项目的不上不下的尴尬处境

作者更有一系列设计模式文章(还在持续更新),图例丰富,少量代码,适合入门,系列文章见末尾跳转

一、命令模式的定义

命令模式:将一个请求封装成对象,用不同的请求实现客户参数化,支持请求排队、记录请求或撤销等操作。

换个好理解的类比:

以前的常规模式就好比——老式电视机或者其他电器,开关集成在机器上,要控制操作、发送命令/请求就得走到机器前面按他的按钮;这样很不方便;

现在命令模式——实现了一个万能遥控器,只要你预先设置好遥控器对应的机器指令,(这里命令模式同时要求机器提供统一的外观接口,比如都要有打开操作、执行操作:具体怎么执行自定义…),然后你就可以一键操控机器。

  1. 客户参数化:机器为抽象实体,可以通过设置修改指向的机器
  2. 请求排队:允许指向多个机器,同一个命令有先后发送顺序
  3. 记录:命令发送时,先打印到日志上(记录命令源、对象)
  4. 撤销:略

二、具体构造

在这里插入图片描述Invoker:事件封装(相当于开关),启动机器相关功能的遥控器,能够通过注册/更改命令控制多种多样的机器,让使用者不需要在持有机器,然后亲自去点击机器;使得使用者和机器解耦,双方没有直接的依赖关系。

ICommand接口和ConcreteCommand:命令接口和具体命令,命令接口提供给遥控器一个统一的外观,具体命令封装了机器对象和调用的机器执行功能

Receiver:接收者,具体的机器,拥有自己的功能和功能名。

一个小流程如下:

interface ICommand{
	void Execute();
}

class TVCommand implements ICommand{
	private TV tv;
	public TVCommand(TV tv){
		this.tv=tv;
	}
	public void Execute(){
		tv.open();
	}
}	

class TV{
	public void open(){
		//打开电视操作
	}
}

class Invoker{
	private ICommand command;
	public void setCommand(ICommand command){
		this.command=command;
	}
	public void executeCommand(){
		command.Execute();
	}
}

//使用者
class Person{
	private Invoker 万能遥控器=new Invoker();
	public void 设置万能遥控器(ICommand command){
		万能遥控器.setCommand(command);
	}
	public void 打开电视(){
		万能遥控器.executeCommand();
	}
}

public class Demo{
	public static void main(String[] args){
		TV 你的电视=new TV();
		Person=new Person();

		//开关设置-具体命令-命令对象.设置万能遥控器(new TVCommand(你的电视));.打开电视();
	}
}

三、命令模式的应用

在Java API事件处理中,如果做过一些小Demo应该都有使用过Java AWT的事件处理

事件源.addXXXListener(new XXXListener())
//一般XXXListener自定义,里面又使用某个类的...方法响应该事件
public class EventDemo1 {
    private Frame frame = new Frame("测试");

//一个Button同时也是一个事件发生器(Invoker)
    private Button button = new Button("submit");
    private TextField textField = new TextField(30);
    public void init (){
    
//注册命令(可以添加多个命令),当button点击,触发Invoker的执行函数
        button.addActionListener(new SubmitListener());
        
        frame.add(textField,BorderLayout.NORTH);
        frame.add(button,BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
    }
    
//相当于ConcreteCommand,提供了如下统一接口
//同时接收一个事件消息类        
    class SubmitListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("用户点击了提交按钮");
            textField.setText("hello world");
        }
    }

    public static void main(String[] args) {
        new EventDemo1().init();
    }
}

即 事件源=Invoker,监听器=命令;
事件源(如Button)注册具体监听器(ActionListener),当事件发生(Button被按下)执行监听器内容(相当于执行命令),监听器可以自定义,可以执行指向另一个类的功能对事件进行相应。

在这里插入图片描述

四、优缺点

优点:

  1. 解耦:事件发生者和相应事件的对象被命令类分割开,降低了耦合度(使用机器的人不需要一直贴着机器操控它,只需要一个遥控器,进行简单设置就可以操控多种机器)
  2. 易维护:方便实现日志,撤销
  3. 易维护:容易添加和修改命令

缺点:

  1. 具体命令类较多,不易管理(很多设计模式都有这个问题,所以对于DIY的命令类,不需要复用情况下,一般设置为内部类)

设计模式系列文章

系列文章:

一、创建型模式——工厂模式
二、创建型模式——单例模式、原型模式
三、创建型模式——建造者模式
四、结构型模式——装饰者模式
五、结构型模式——代理、适配器模式
六、结构型模式——外观模式
七、结构型模式——三合一(组合模式、桥接模式、享元模式)
八、行为型模式——观察者模式
九、行为型模式——迭代器模式
十、行为型模式——模板方法、策略方法模式
十一、行为型模式——命令模式


结尾

作者长期更新,如果觉得本文还算不错的话,请给我一个大大的赞!!!
如果非常赞同这篇文章,请关注我,持续了解更多精彩博文!!!

作者主攻Java Web方向,平时长期更新Java Web基础概念文章,以及算法和数据结构——【一日双题—见微知著】系列。同时设计模式系列也会尽快一月内完结

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码之狐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值