• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

RomanLin

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

【设计模式与体系结构】行为型模式-命令模式

简介

命令模式(Command Pattern)是一种行为型模式,它将请求封装成一个对象,从而你可以用不同的请求将客户参数化,对请求排队或记录请求日志,以及支持可撤销操作。

命令模式的角色

  • 抽象命令(Command)接口:定义抽象命令接口,通常包含一个execute()方法
  • 具体命令(Concrete Command)类:实现抽象命令接口,负责调用接收者的相应操作,并将接收者对象绑定到该命令中
  • 接收者(Receiver)类:知道如何执行与请求相关的操作,实现具体业务逻辑
  • 调用者(Invoker)类:负责调用命令者类执行相关请求,不直接与接收者交互
  • 客户端:创建命令对象并设置其接收者对象,然后将命令传给调用者对象

命令模式的优点

  1. 请求与实现的解耦:命令者模式将调用者和接收者进行解耦,使得二者无需直接交互,提高了系统的可维护性和可扩展性
  2. 支持撤销与重做:可以在命令类中实现撤销方法和重做方法,提高系统的交互性
  3. 符合开闭原则:只需要新增具体命令类,而无需修改已有的代码逻辑,提高了系统的可维护性和可扩展性

命令模式的缺点

  1. 系统复杂性增加:每增加一个具体命令,都需要添加一个具体命令类
  2. 维护难度高:当具体命令的数量较多时,维护会比较困难

命令模式的使用场景

  1. 菜单系统:在图形界面应用程序中,菜单系统通常会有各种操作:打开文件、保存文件等。可以将每个菜单项封装成一个命令对象,方便管理和执行
  2. 任务队列:将请求封装成命令对象以后,可以将这些命令对象放入队列中,实现任务的排队和异步执行
  3. 撤销和重做功能:在文本编辑器、图形处理软件等应用中,经常需要实现撤销和重做操作,命令模式可以很好地支持这一功能。

正文

打开一个图形化界面,或者是网页界面,我们常常会看到有“最大化按钮”、“最小化按钮”以及“关闭界面按钮”等等。这些按钮的逻辑各不相同,但对于界面来说,都仅仅只是一个按钮。由于用户也有个性化设置需求,有些用户喜欢修改这些按钮的顺序,那么如果这些按钮就像一些电器的插头一样,而按钮的位置就像插座一样,只需要插拔一下,就会十分方便。下面我们就以图形化界面的按钮功能作为案例,进行代码分析。

首先,定义一个接收者(Receiver)接口 Receiver.java。接收者仅负责执行具体的业务逻辑,无需持有外部依赖,且一个系统会有多种业务逻辑,因此设计为接口较为合适。

public interface Receiver {
	void action();//执行具体业务逻辑
}

以“最大化按钮”为案例,定义一个 MaximiseReceiver.java,负责执行“窗口最大化”的功能需求。

public class MaximiseReceiver implements Receiver {

	@Override
	public void action() {
		System.out.println("窗口最大化");
	}

}

定义一个抽象命令类 Command.java。该类需要注入一个接收者对象,并且要有一个抽象的执行方法(execute()方法),因此设计为一个抽象类较为合适。

public abstract class Command {
	private Receiver receiver;

	public Command(Receiver receiver) {
		this.receiver = receiver;
	}
	
	public Receiver getReceiver() {
		return receiver;
	}

	public void setReceiver(Receiver receiver) {
		this.receiver = receiver;
	}

	abstract void execute();
}

定义一个“最大化按钮”的具体命令类 MaximiseCommand.java

public class MaximiseCommand extends Command {
	
	public MaximiseCommand(Receiver receiver) {
		super(receiver);
	}

	@Override
	public void execute() {
		getReceiver().action();
	}
	
}

定义一个调用者类 Invoker.java。该类需要持有一个具体命令对象,并且可以调用具体命令对象的命令,可以设计为一个普通的类,也可以设计为一个抽象类。

public class Invoker {
	private Command mCommand;
	
	public Invoker(Command command) {
		this.mCommand = command;
	}
	
	public void setCommand(Command command) {
		this.mCommand = command;
	}
	
	public void call() {
		mCommand.execute();
	}
}

定义一个客户端 Client.java

public class Client {
	public static void main(String[] args) {
		Receiver receiver = new MaximiseReceiver();
		Command maximiseCommand = new MaximiseCommand(receiver);
		Invoker invoker = new Invoker(maximiseCommand);
		invoker.call();
	}
}

posted on 2025-02-09 13:15  RomanLin  阅读(35)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3