命令模式(Command Pattern)——将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持科撤销的操作。
命令模式适用于“请求-响应”模式的功能,将用户的请求封装成对象(命令),用户需要执行什么样的操作,就调用什么样的命令,而无需知道命令的执行逻辑是什么。
命令模式主要包含以下几个概念:
1、Command:所有命令的抽象类,一般需要对外公开一个执行命令的方法execute,如有需要还需提供一个命令的撤销方法undo。
2、ConcreteCommand:命令的实现类。
3、Invoker:调用者,负责命令的调度。
4、Reveiver:接收者,负责命令的接收和执行。
5、Client:客户端,命令的发起者。
比如,一个有存取款功能的ATM机,它可以向某个银行的卡里存款,也可以从任何支持银联接口的银行卡里取款。不同的银行系统对存款、取款功能的实现均有不同,我们不关心银行怎么实现,只要点击ATM上的按钮就行了。这个例子中,银行的存款和取款分别为两个具体的命令实现类(ConcreteCommand);ATM机充当调用者(Invoker),负责调用银行存款或取款的命令;银行的系统为接收者(Reveiver),处理存款和取款的业务逻辑;使用ATM机的人就是客户端。
首先定义一个命令的抽象类,只有两个方法,执行和撤销:
public interface Command { public void execute(); public void undo(); }
模拟两个银行的系统,建行(CCB)和招行(CMB),简单一点,只有存款和取款的功能。为了模拟银行系统实现的差异,将存款、取款方法取成不同的名字。
建行:
public class Ccb { public void cunqian(long amount) { System.out.println("向建设银行存入金额:" + amount); } public void quqian(long amount) { System.out.println("从建设银行取出金额:" + amount); } }
招行:
public class Cmb{ public void saveMoney(long amount) { System.out.println("向招商银行存入金额:" + amount); } public void getMoney(long amount) { System.out.println("从招商银行取出金额:" + amount); } }
将银行的存款、取款动作封装成命令对象。为了避免太复杂,存款命令的撤销就当再取出来,取款命令的撤销就再存回去。
建行的存款命令:
public class CcbDepositCommand implements Command { private Ccb ccb = new Ccb(); @Override public void execute() { ccb.cunqian(100); } @Override public void undo() { ccb.quqian(100); } }
建行的取款命令:
public class CcbWithdrawCommand implements Command { private Ccb ccb = new Ccb(); @Override public void execute() { ccb.quqian(100); } @Override public void undo() { ccb.cunqian(100); } }
招行的存款命令:
public class CmbDepositCommand implements Command { private Cmb cmb = new Cmb(); @Override public void execute() { cmb.saveMoney(100); } @Override public void undo() { cmb.getMoney(100); } }
招行的取款命令:
public class CmbWithdrawCommand implements Command { private Cmb cmb = new Cmb(); @Override public void execute() { cmb.getMoney(100); } @Override public void undo() { cmb.saveMoney(100); } }
ATM机刚出厂时可能还没设置任何命令,所以为每个按钮预置一个什么都不做的命令:
public class NoCommand implements Command { @Override public void execute() { } @Override public void undo() { } }
现在来实现一个刚出厂的ATM机,它可能完成任何银行的存取款命令,这些命令由负责购买ATM机的银行日后自行规划:
public class Atm { private Command[] command; public Atm(){ this.command = new Command[]{new NoCommand()}; } //设置一组要执行的命令 public void setCommand(Command command[]) { this.command = command; } //执行命令的方法 public void action(int i) { this.command[i].execute(); } //撤销命令的方法 public void cancel(int i) { this.command[i].undo(); } }
现在假设要实现一个建行的ATM机,只有三个功能:1是向建行存款;2是从建行取款;3从招行取款。只要为ATM设置上相应的命令就可以了。测试类:
public class Test { /** * 命令模式——将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。 * 命令模式也支持科撤销的操作。 * * @param args */ public static void main(String[] args) { //调用者来执行命令 Atm atm = new Atm(); Command[] commands = new Command[3]; commands[0] = new CcbDepositCommand(); commands[1] = new CcbWithdrawCommand(); commands[2] = new CmbWithdrawCommand(); atm.setCommand(commands); atm.action(0); atm.cancel(0); atm.action(1); atm.cancel(1); atm.action(2); atm.cancel(2); } }
当然,如果我们不适用ATM机,直接到银行的窗口,营业员也可以直接调用系统相应的命令:
//直接执行具体命令 Command command = new CcbDepositCommand(); command.execute(); command.undo();
命令模式的扩展性、封装性很好,可以很好的将用户请求与请求的实现解耦,对需求的变化也更容易扩展。但一个很简单的请求都需要封装为一个命令,也会导致类的膨胀,因此开发时需根据实际需要判断是否使用命令模式。
相关推荐
以下是一些在尚学堂300Java设计模式部分学习笔记中涉及的设计模式的知识点: 创建型模式: 创建型模式主要解决对象创建的问题,确保系统的灵活性和封装创建细节。学习笔记中提到了5种创建型模式: 1. 单例模式...
`CommandPattern.java`可能包含命令的创建和执行,笔记会讨论如何实现命令和调用者之间的解耦。 这些设计模式的实现和笔记结合,不仅帮助理解设计模式的基本概念,还提供了实际的编码实践,有助于开发者在Eclipse...
### 23种设计模式学习笔记 #### 一、软件设计模式的概念与意义 **概念:** 软件设计模式(Software Design Pattern),又称设计模式,是一套被广泛采用、经过整理和分类的代码设计经验总结。它针对软件设计过程中...
### 设计模式学习笔记知识点概览 #### 一、引言 设计模式是软件工程领域中一种非常重要的概念,它代表了一种最佳实践的方式,帮助开发者解决特定问题时能够更加高效、灵活。良葛格的《Design Pattern学习笔记》不仅...
本篇文章是对一份设计模式学习资料的深入解读,这份资料包含了19种经典的设计模式,并提供了C#示例代码,适用于学习和复习。下面将逐一介绍这些设计模式及其核心概念。 #### 1. 简单工厂模式 (Simple Factory ...
行为型模式如命令模式(Command)、观察者模式(Observer)关注对象的行为和通信。这些模式为解决特定问题提供了标准化的解决方案,提高了代码的复用性和可读性。 理解并熟练运用这些知识点对于软件工程师来说至关...
13. **命令模式(Command)**:将请求封装为一个对象,从而使你可以使用不同的请求、队列请求、记录请求日志以及支持可撤销的操作。 14. **解释器模式(Interpreter)**:给定一种语言,定义它的文法表示,并提供一...
本学习笔记和示例代码将深入探讨23种经典的GOF设计模式,并以Java语言为实现基础。 1. **单例模式(Singleton)**:确保一个类只有一个实例,并提供全局访问点。在Java中,通常使用双重检查锁定(Double-Checked ...
- **观察者设计模式** - 观察者模式的概念:定义对象之间的一对多依赖关系。 - 观察者模式的实现:使用Subject和Observer接口。 - **正则表达式** - 正则表达式的用途:模式匹配。 - Pattern类与Matcher类的使用...
### Linux Shell Sed 学习笔记:深入理解与实践 #### Sed 概览 Sed(Stream Editor)是一种功能强大的文本处理工具,适用于Unix/Linux环境下的流编辑操作。它能够读取输入流(如文件或标准输入),进行模式匹配、...
### expect学习笔记及实例详解 #### 一、expect简介与基本语法 **expect** 是一个基于 **Tcl** 的程序,主要用于自动化交互式命令。它最初由 Don Libes 在 1990 年代初开发,目的是为了解决通过自动化方式与需要...
集合了 所有的 Unix命令大全 登陆服务器时输入 公帐号 openlab-open123 telnet 192.168.0.23 自己帐号 sd08077-you0 ftp工具 192.168.0.202 tools-toolss 老师测评网址 http://172.16.0.198:8080/poll/ 各个 ...