`
wuhongyu
  • 浏览: 406931 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

JAVA设计模式学习笔记6——命令模式(Command Pattern)

阅读更多

命令模式(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();

 

    命令模式的扩展性、封装性很好,可以很好的将用户请求与请求的实现解耦,对需求的变化也更容易扩展。但一个很简单的请求都需要封装为一个命令,也会导致类的膨胀,因此开发时需根据实际需要判断是否使用命令模式。

 

 

 

 

 

 

 

0
0
分享到:
评论
1 楼 di1984HIT 2015-02-05  
命令模式写的很好!

相关推荐

    300Java设计模式部分学习笔记

    以下是一些在尚学堂300Java设计模式部分学习笔记中涉及的设计模式的知识点: 创建型模式: 创建型模式主要解决对象创建的问题,确保系统的灵活性和封装创建细节。学习笔记中提到了5种创建型模式: 1. 单例模式...

    java设计模式源码和笔记(第一部分)

    `CommandPattern.java`可能包含命令的创建和执行,笔记会讨论如何实现命令和调用者之间的解耦。 这些设计模式的实现和笔记结合,不仅帮助理解设计模式的基本概念,还提供了实际的编码实践,有助于开发者在Eclipse...

    23中设计模式学习笔记.docx

    ### 23种设计模式学习笔记 #### 一、软件设计模式的概念与意义 **概念:** 软件设计模式(Software Design Pattern),又称设计模式,是一套被广泛采用、经过整理和分类的代码设计经验总结。它针对软件设计过程中...

    良葛格DesignPattern学习笔记

    ### 设计模式学习笔记知识点概览 #### 一、引言 设计模式是软件工程领域中一种非常重要的概念,它代表了一种最佳实践的方式,帮助开发者解决特定问题时能够更加高效、灵活。良葛格的《Design Pattern学习笔记》不仅...

    设计模式笔记总结 含C#示例代码 复习好帮手

    本篇文章是对一份设计模式学习资料的深入解读,这份资料包含了19种经典的设计模式,并提供了C#示例代码,适用于学习和复习。下面将逐一介绍这些设计模式及其核心概念。 #### 1. 简单工厂模式 (Simple Factory ...

    软件体系结构与设计模式课堂笔记.docx

    行为型模式如命令模式(Command)、观察者模式(Observer)关注对象的行为和通信。这些模式为解决特定问题提供了标准化的解决方案,提高了代码的复用性和可读性。 理解并熟练运用这些知识点对于软件工程师来说至关...

    Gof design pattern 中文/英文版+web+学习笔记

    13. **命令模式(Command)**:将请求封装为一个对象,从而使你可以使用不同的请求、队列请求、记录请求日志以及支持可撤销的操作。 14. **解释器模式(Interpreter)**:给定一种语言,定义它的文法表示,并提供一...

    DesignPattern:设计模式的学习笔记和示例代码

    本学习笔记和示例代码将深入探讨23种经典的GOF设计模式,并以Java语言为实现基础。 1. **单例模式(Singleton)**:确保一个类只有一个实例,并提供全局访问点。在Java中,通常使用双重检查锁定(Double-Checked ...

    JAVA经典教材笔记

    - **观察者设计模式** - 观察者模式的概念:定义对象之间的一对多依赖关系。 - 观察者模式的实现:使用Subject和Observer接口。 - **正则表达式** - 正则表达式的用途:模式匹配。 - Pattern类与Matcher类的使用...

    linux shell Sed学习笔记

    ### Linux Shell Sed 学习笔记:深入理解与实践 #### Sed 概览 Sed(Stream Editor)是一种功能强大的文本处理工具,适用于Unix/Linux环境下的流编辑操作。它能够读取输入流(如文件或标准输入),进行模式匹配、...

    expect学习笔记及实例详解

    ### expect学习笔记及实例详解 #### 一、expect简介与基本语法 **expect** 是一个基于 **Tcl** 的程序,主要用于自动化交互式命令。它最初由 Don Libes 在 1990 年代初开发,目的是为了解决通过自动化方式与需要...

    2009 达内Unix学习笔记

    集合了 所有的 Unix命令大全 登陆服务器时输入 公帐号 openlab-open123 telnet 192.168.0.23 自己帐号 sd08077-you0 ftp工具 192.168.0.202 tools-toolss 老师测评网址 http://172.16.0.198:8080/poll/ 各个 ...

Global site tag (gtag.js) - Google Analytics