设计模式(14)--Command(命令模式)--行为型
作者QQ:1095737364 QQ群:123300273 欢迎加入!
1.模式定义:
2.模式特点:
3.使用场景:
4.模式实现:

(1)客户端(Client)角色:
public class Client {
public static void main(String[] args) {
//创建接收者
Receiver receiver = new Receiver();
//创建命令对象,设定它的接收者
Command command = new ConcreteCommand(receiver);
//创建请求者,把命令对象设置进去
Invoker invoker = new Invoker(command);
//执行方法
invoker.action();
}
}
(2)命令(Command)角色:
public interface Command {
/**
* 执行方法
*/
void execute();
}
(3)具体命令(ConcreteCommand)角色:
public class ConcreteCommand implements Command {
//持有相应的接收者对象
private Receiver receiver = null;
/**
* 构造方法
*/
public ConcreteCommand(Receiver receiver){
this.receiver = receiver;
}
@Override
public void execute() {
//通常会转调接收者对象的相应方法,让接收者来真正执行功能
receiver.action();
}
}
(4)请求者(Invoker)角色:
public class Invoker {
/**
* 持有命令对象
*/
private Command command = null;
/**
* 构造方法
*/
public Invoker(Command command){
this.command = command;
}
/**
* 行动方法
*/
public void action(){
command.execute();
}
}
(5)接收者(Receiver)角色:
public class Receiver {
/**
* 真正执行命令相应的操作
*/
public void action(){
System.out.println("执行操作");
}
}
AudioPlayer系统

(1)接收者角色,由录音机类扮演
public class AudioPlayer {
public void play(){
System.out.println("播放...");
}
public void rewind(){
System.out.println("倒带...");
}
public void stop(){
System.out.println("停止...");
}
}
(2)抽象命令角色类
public interface Command {
/**
* 执行方法
*/
public void execute();
}
(3)具体命令角色类
public class PlayCommand implements Command {
private AudioPlayer myAudio;
public PlayCommand(AudioPlayer audioPlayer){
myAudio = audioPlayer;
}
/**
* 执行方法
*/
@Override
public void execute() {
myAudio.play();
}
}
public class RewindCommand implements Command {
private AudioPlayer myAudio;
public RewindCommand(AudioPlayer audioPlayer){
myAudio = audioPlayer;
}
@Override
public void execute() {
myAudio.rewind();
}
}
public class StopCommand implements Command {
private AudioPlayer myAudio;
public StopCommand(AudioPlayer audioPlayer){
myAudio = audioPlayer;
}
@Override
public void execute() {
myAudio.stop();
}
}
(4)请求者角色,由键盘类扮演
public class Keypad {
private Command playCommand;
private Command rewindCommand;
private Command stopCommand;
public void setPlayCommand(Command playCommand) {
this.playCommand = playCommand;
}
public void setRewindCommand(Command rewindCommand) {
this.rewindCommand = rewindCommand;
}
public void setStopCommand(Command stopCommand) {
this.stopCommand = stopCommand;
}
/**
* 执行播放方法
*/
public void play(){
playCommand.execute();
}
/**
* 执行倒带方法
*/
public void rewind(){
rewindCommand.execute();
}
/**
* 执行播放方法
*/
public void stop(){
stopCommand.execute();
}
}
(5)客户端角色,由茱丽小女孩扮演
public class Julia {
public static void main(String[]args){
//创建接收者对象
AudioPlayer audioPlayer = new AudioPlayer();
//创建命令对象
Command playCommand = new PlayCommand(audioPlayer);
Command rewindCommand = new RewindCommand(audioPlayer);
Command stopCommand = new StopCommand(audioPlayer);
//创建请求者对象
Keypad keypad = new Keypad();
keypad.setPlayCommand(playCommand);
keypad.setRewindCommand(rewindCommand);
keypad.setStopCommand(stopCommand);
//测试
keypad.play();
keypad.rewind();
keypad.stop();
keypad.play();
keypad.stop();
}
}

5.优缺点:
(1)命令模式的优点:
(2)命令模式的缺点:
6.宏命令

(1)系统需要一个代表宏命令的接口,以定义出具体宏命令所需要的接口。
public interface MacroCommand extends Command {
/**
* 宏命令聚集的管理方法
* 可以添加一个成员命令
*/
public void add(Command cmd);
/**
* 宏命令聚集的管理方法
* 可以删除一个成员命令
*/
public void remove(Command cmd);
}
(2)具体的宏命令MacroAudioCommand类负责把个别的命令合成宏命令。
public class MacroAudioCommand implements MacroCommand {
private List<Command> commandList = new ArrayList<Command>();
/**
* 宏命令聚集管理方法
*/
@Override
public void add(Command cmd) {
commandList.add(cmd);
}
/**
* 宏命令聚集管理方法
*/
@Override
public void remove(Command cmd) {
commandList.remove(cmd);
}
/**
* 执行方法
*/
@Override
public void execute() {
for(Command cmd : commandList){
cmd.execute();
}
}
}
(3)客户端类Julia
public class Julia {
public static void main(String[]args){
//创建接收者对象
AudioPlayer audioPlayer = new AudioPlayer();
//创建命令对象
Command playCommand = new PlayCommand(audioPlayer);
Command rewindCommand = new RewindCommand(audioPlayer);
Command stopCommand = new StopCommand(audioPlayer);
MacroCommand marco = new MacroAudioCommand();
marco.add(playCommand);
marco.add(rewindCommand);
marco.add(stopCommand);
marco.execute();
}
}

7.撤销命令
/**
* 包含撤销命令的接口
* @author
*/
public interface Command {
//执行方法
void execute();
//撤销方法
void undo();
}
/**
* 具体命令 -- 创建目录
* @author
*/
public class CreateDirCommand implements Command {
private String dirName;
MakeDir makeDir;
public CreateDirCommand(MakeDir makeDir,String dirName) {
this.makeDir = makeDir;
this.dirName = dirName;
}
@Override
public void execute() {
makeDir.createDir(dirName);
} @Override
public void undo() {
makeDir.deleteDir(dirName);
}
}
/**
* 命令接受者
* 包含两个命令:创建目录、删除目录
* @author
*/
public class MakeDir {
//创建目录
public void createDir(String name){
File dir = new File(name);
if (dir.exists()) {
System.out.println("创建目录 " + name + " 失败,目标目录已经存在");
}else{
//创建目录
if (dir.mkdirs()) {
System.out.println("创建目录 " + name + " 成功");
} else {
System.out.println("创建目录 " + name + " 失败");
}
}
}
//删除目录
public void deleteDir(String name){
File dir = new File(name);
if(dir.exists()) {
if(dir.delete()){
System.out.println("删除目录 " + name + " 成功");
}else{
System.out.println("删除目录 " + name + " 失败");
}
}else{
System.out.println("删除目录 " + name + " 失败,目标目录不存在");
}
}
}
/**
* 请求者
* @author
*/
public class RequestMakeDir {
Command createCommand;
public void setCreateCommand(Command command) {
this.createCommand = command;
}
public void executeCreateCommand(){
createCommand.execute();
}
public void undoCreateCommand(){
createCommand.undo();
}
}
/**
* 测试
* @author
*/
public class Client {
public static void main(String[] args) {
String dir = "E:\\command2017"; //创建接收者
MakeDir makeDir = new MakeDir();
//创建具体命令并且指定接收者
Command create_command = new CreateDirCommand(makeDir,dir);
//创建请求者
RequestMakeDir request = new RequestMakeDir();
//设置命令
request.setCreateCommand(create_command);
/***********创建目录及撤销**************/
//创建目录
request.executeCreateCommand();
//撤销
request.undoCreateCommand();
}
}
创建目录 E:\command2017 成功
删除目录 E:\command2017 成功
8.多次撤销
/**
* 包含撤销命令的接口
* @author
*/
public interface Command {
//执行方法
void execute(String dirName);
//撤销方法
void undo();
}
/**
* 具体命令 -- 创建目录
* @author
*/
public class CreateDirCommand implements Command {
private ArrayList<String> dirNameList; //记录 这里用list实现
private MakeDir makeDir;
public CreateDirCommand(MakeDir makeDir) {
dirNameList = new ArrayList<String>();
this.makeDir = makeDir;
} @Override
public void execute(String dirName) {
makeDir.createDir(dirName);
dirNameList.add(dirName);
} @Override
public void undo() {
if(dirNameList.size()>0){
makeDir.deleteDir(dirNameList.get(dirNameList.size()-1));
dirNameList.remove(dirNameList.size()-1);
}else{
System.out.println("没有需要撤销的操作!");
}
}
}
/**
* 命令接受者
* 包含两个命令:创建目录、删除目录
* @author
*/
public class MakeDir {
//创建目录
public void createDir(String name){
File dir = new File(name);
if (dir.exists()) {
System.out.println("创建目录 " + name + " 失败,目标目录已经存在");
}else{
//创建目录
if (dir.mkdirs()) {
System.out.println("创建目录 " + name + " 成功");
} else {
System.out.println("创建目录 " + name + " 失败");
}
}
}
//删除目录
public void deleteDir(String name){
File dir = new File(name);
if(dir.exists()) {
if(dir.delete()){
System.out.println("删除目录 " + name + " 成功");
}else{
System.out.println("删除目录 " + name + " 失败");
}
}else{
System.out.println("删除目录 " + name + " 失败,目标目录不存在");
}
}
}
/**
* 请求者
* @author
*/
public class RequestMakeDir {
Command createCommand;
public void setCreateCommand(Command command) {
this.createCommand = command;
}
public void executeCreateCommand(String dirName){
createCommand.execute(dirName);
}
public void undoCreateCommand(){
createCommand.undo();
}
}
/**
* 测试
* @author
*/
public class Client {
public static void main(String[] args) {
//创建接收者
MakeDir makeDir = new MakeDir();
//创建具体命令并且指定接收者
Command create_command = new CreateDirCommand(makeDir);
//创建请求者
RequestMakeDir request = new RequestMakeDir();
//设置命令
request.setCreateCommand(create_command);
/***********创建目录及撤销**************/
//创建目录
request.executeCreateCommand("E:\\command\\2017");
request.executeCreateCommand("E:\\command\\2018");
request.executeCreateCommand("E:\\command\\2019");
request.executeCreateCommand("E:\\command\\2020");
//多次撤销
request.undoCreateCommand();
request.undoCreateCommand();
request.undoCreateCommand();
request.undoCreateCommand();
request.undoCreateCommand();
}
}
创建目录 E:\command\2017 成功
创建目录 E:\command\2018 成功
创建目录 E:\command\2019 成功
创建目录 E:\command\2020 成功
删除目录 E:\command\2020 成功
删除目录 E:\command\2019 成功
删除目录 E:\command\2018 成功
删除目录 E:\command\2017 成功
没有需要撤销的操作!
9.命令队列
/**
* 抽象命令角色类
* @author
*/
public interface Command {
/**
* 执行方法
*/
void execute();
}
/**
* 接收者角色类 - Java工程师
* @author
*/
public class JavaCoder {
/**
* 真正执行命令相应的操作
*/
public void work(String task){
System.out.println("java工程师要完成【"+task+"】");
}
}
/**
* 接收者角色类 - H5工程师
* @author
*/
public class H5Coder {
/**
* 真正执行命令相应的操作
*/
public void work(String task){
System.out.println("H5工程师要完成【"+task+"】");
}
}
/**
* 具体命令 -- Java工程师执行任务
* @author
*/
public class JavaCommand implements Command{
//持有相应的接收者对象
private JavaCoder javaCoder;
//具体任务
private String task;
/**
* 构造方法
*/
public JavaCommand(JavaCoder javaCoder,String task){
this.javaCoder = javaCoder;
this.task = task;
} @Override
public void execute() {
//通常会转调接收者对象的相应方法,让接收者来真正执行功能
javaCoder.work(this.task);
}
}
/**
* 具体命令 -- H5工程师执行任务
* @author
*/
public class H5Command implements Command{
//持有相应的接收者对象
private H5Coder h5Coder;
//具体任务
private String task;
/**
* 构造方法
*/
public H5Command(H5Coder h5Coder,String task){
this.h5Coder = h5Coder;
this.task = task;
} @Override
public void execute() {
//通常会转调接收者对象的相应方法,让接收者来真正执行功能
h5Coder.work(this.task);
}
}
/**
* CommandQueue命令队列类
* @author
*/
public class CommandQueue {
//定义一个ArrayList来存储命令队列
private ArrayList<Command> commands = new ArrayList<Command>(); public void addCommand(Command command) {
commands.add(command);
} public void removeCommand(Command command) {
commands.remove(command);
} //循环调用每一个命令对象的execute()方法
public void execute() {
for(Command command : commands) {
command.execute();
}
}
}
/**
* 请求发送者类Manager针对CommandQueue编程
* @author
*/
public class Manager {
private CommandQueue commandQueue; //维持一个CommandQueue对象的引用 //构造注入
public Manager(CommandQueue commandQueue) {
this. commandQueue = commandQueue;
} //设值注入
public void setCommandQueue(CommandQueue commandQueue) {
this.commandQueue = commandQueue;
} //调用CommandQueue类的execute()方法
public void call() {
commandQueue.execute();
}
}
测试:
/**
*
* @author
*/
public class Client {
public static void main(String[] args) {
//创建接收者
JavaCoder javaCoder = new JavaCoder();
H5Coder h5Coder = new H5Coder();
//创建命令对象
JavaCommand javaCommand = new JavaCommand(javaCoder,"登录模块的后台代码");
H5Command h5Command = new H5Command(h5Coder,"登录模块的前台代码");
//创建命令对象队列
CommandQueue commandqueue = new CommandQueue();
commandqueue.addCommand(javaCommand);
commandqueue.addCommand(h5Command);
//创建请求者,把命令对象设置进去
Manager manager = new Manager(commandqueue);
//执行方法
manager.call();
}
}
java工程师要完成【登录模块的后台代码】
H5工程师要完成【登录模块的前台代码】
10.请求日志
/**
* 抽象命令类,由于需要将命令对象写入文件,因此它实现了Serializable接口
* @author
*/
public abstract class Command implements Serializable {
private static final long serialVersionUID = 1L; protected String name; //命令名称
protected String args; //命令参数
protected Operator operator; //接收者对象
public Command(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public void setOperator(Operator operator) {
this.operator = operator;
}
//声明两个抽象的执行方法execute()
public abstract void execute(String args);
public abstract void execute();
}
/**
* 请求接收者 -- 由于Operator类的对象是Command的成员对象,它也将随Command对象一起写入文件,因此Operator也需要实现Serializable接口
* @author
*/
public class Operator implements Serializable{
private static final long serialVersionUID = 1L; public void insert(String args) {
System.out.println("新增数据:" + args);
} public void update(String args) {
System.out.println("修改数据:" + args);
} public void delete(String args) {
System.out.println("删除数据:" + args);
}
}
/**
* 具体命令角色类 -- 插入命令
* @author
*/
public class InsertCommand extends Command{
public InsertCommand(String name) {
super(name);
} public void execute(String args) {
this.args = args;
operator.insert(args);
} public void execute() {
operator.insert(this.args);
}
}
/**
* 具体命令角色类 -- 修改命令
* @author
*/
public class UpdateCommand extends Command{
public UpdateCommand(String name) {
super(name);
} public void execute(String args) {
this.args = args;
operator.update(args);
} public void execute() {
operator.update(this.args);
}
}
/**
* 具体命令角色类 -- 删除命令
* @author
*/
public class DeleteCommand extends Command{
public DeleteCommand(String name) {
super(name);
} public void execute(String args) {
this.args = args;
operator.delete(args);
} public void execute() {
operator.delete(this.args);
}
}
import com.designpattern.utils.FileUtil;
/**
* 请求发送者
* @author
*/
public class SqlExecuteTool {
//定义一个集合来存储每一次操作时的命令对象
private ArrayList<Command> commands = new ArrayList<Command>();
private Command command; //注入具体命令对象
public void setCommand(Command command) {
this.command = command;
} //执行配置文件修改命令,同时将命令对象添加到命令集合中
public void call(String args) {
command.execute(args);
commands.add(command);
} //记录请求日志,生成日志文件,将命令集合写入日志文件
public void save() {
FileUtil.writeCommands(commands);
} //从日志文件中提取命令集合,并循环调用每一个命令对象的execute()方法来实现配置文件的重新设置
public void recover() {
ArrayList list = FileUtil.readCommands();
for (Object obj : list) {
((Command)obj).execute();
}
}
}
package com.designpattern.Command.extend.RequestLog;
/**
* 测试
* @author
*/
public class Client {
public static void main(String[] args) {
SqlExecuteTool tool = new SqlExecuteTool(); //定义请求发送者
Operator operator = new Operator(); //定义请求接收者 Command command; //执行了很多次SQL
command = new InsertCommand("增加");
command.setOperator(operator);
tool.setCommand(command);
tool.call("insert xxx"); command = new InsertCommand("增加");
command.setOperator(operator);
tool.setCommand(command);
tool.call("insert xxx"); command = new UpdateCommand("修改");
command.setOperator(operator);
tool.setCommand(command);
tool.call("update xxx"); command = new DeleteCommand("删除");
command.setOperator(operator);
tool.setCommand(command);
tool.call("delete xxx"); System.out.println("-------------------------------------");
System.out.println("保存执行的sql");
tool.save();
System.out.println("-------------------------------------");
System.out.println("恢复执行的sql");
System.out.println("-------------------------------------");
tool.recover();
}
}
新增数据:insert xxx
新增数据:insert xxx
修改数据:update xxx
删除数据:delete xxx
-------------------------------------
保存执行的sql
-------------------------------------
恢复执行的sql
-------------------------------------
新增数据:insert xxx
新增数据:insert xxx
修改数据:update xxx
删除数据:delete xxx
设计模式(14)--Command(命令模式)--行为型的更多相关文章
- 设计模式(十四):Command命令模式 -- 行为型模式
1.概述 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来 ...
- 设计模式14:Command 命令模式(行为型模式)
Command 命令模式(行为型模式) 耦合与变化 耦合是软件不能抵御变化的根本性原因.不仅实体对象与实体对象之间存在耦合关系,实体对象与行为操作之间也存在耦合关系. 动机(Motivation) 在 ...
- 第14章 命令模式(Command Pattern)
原文 第14章 命令模式(Command Pattern) 命令模式(Command Pattern) 概述 在软件系统中,“行为请求者”与“行为实现者”通常呈现一种“紧耦合”.但在某些场合,比如 ...
- 设计模式之第14章-命令模式(Java实现)
设计模式之第14章-命令模式(Java实现) “小明,滚出去.”“小明,这个问题怎么做?”(可怜的小明无奈躺枪.小明:老师,我和你有什么仇什么怨,我和你有什么仇什么怨啊到底...老师:小明,滚出去.习 ...
- C++设计模式-Command命令模式
Command命令模式作用:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 由于“行为请求者”与“行为实现者”的紧耦合,使用命令模式 ...
- 22、Command 命令模式
1.command 命令模式 命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指 ...
- 设计模式学习之命令模式(Command,行为型模式)(12)
一.命令模式的定义 命令模式属于对象的行为型模式.命令模式是把一个操作或者行为抽象为一个对象中,通过对命令的抽象化来使得发出命令的责任和执行命令的责任分隔开.命令模式的实现可以提供命令的撤销和恢复功能 ...
- c#设计模式系列:命令模式(Command Pattern)
引言 命令模式,我感觉"命令"就是任务,执行了命令就完成了一个任务.或者说,命令是任务,我们再从这个名字上并不知道命令的发出者和接受者分别是谁,为什么呢?因为我们并不关心他们是谁, ...
- C#设计模式系列:命令模式(Command)
1.命令模式简介 1.1>.定义 命令模式的目的是解除命令发出者和接收者之间的紧密耦合关系,使二者相对独立,有利于程序的并行开发和代码的维护.命令模式的核心思想是将请求封装为一个对象,将其作为命 ...
随机推荐
- 深入字节码理解invokeSuper无限循环的原因
来一段简单的cglib代码 public class SampleClass { public void test(){ System.out.println("hello world&qu ...
- pinnet 计算云分区
fdisk /dev/xvdemne mnlEnterEnter 9G-98G-98G-478M-28G-28G-28G mw #设置文件格式mkfs -t ext4 /dev/xvde5mkfs - ...
- JavaScript getter和setter
对象的属性是由属性名name,值key,和其他特性(可读写性 writable,可枚举性enumerable,可配置性configurable)组成的.从ES5开发,提供了getter和setter ...
- iOS 数据持久化-- FMDB
一.简介 1.什么是FMDB FMDB是iOS平台的SQLite数据库框架 FMDB以OC的方式封装了SQLite的C语言API 2.FMDB的优点 使用起来更加面向对象,省去了很多麻烦.冗余的C语言 ...
- Python相关在线文档手册地址
Python相关: 五星推荐:http://python.usyiyi.cn/ Python 2.7官方中文文档:http://doc.iplaypy.com/python2/ 英文: htt ...
- vs 2017 IIS EXPRESS 增加局域网访问
在VS调试站点,默认使用IISExpress,locall+端口,为了使用IP地址.多域名调试,找到 IISExpress下的applicationhost.config,在目标站点下增加类似行: & ...
- cmd/git设置alias提高效率
cmd设置alias 在cmd或者git中有有些命令是比较长的,却需要频繁的使用,那么我们就可以设置alias来简化操作,无形中减少大量的宝贵时间,具体步骤如下. 第一步: 创建cmd_alias.b ...
- Azure Storage架构介绍
Windows Azure Storage由三个重要部分或者说三种存储数据服务组成,它们是:Windows Azure Blob.Windows Azure Table和Windows Azure Q ...
- Android入门学习总结
1.Manifest.xml是程序运行时读取的文件,是核心的配置文件:也是从中读取Activity 2.主要的代码文件存放在MainActivity.java,里面固定会有onCreate函数会通过s ...
- asp.net调用js方法
C#前台js调用后台代码 前台js <script type="text/javascript" language="javascript"> fu ...