走穿java23种设计模式-14命令模式详解
命令模式又称行为模式或者交易模式。
命令模式也是一个比较少见的设计模式。但是说白了就是方法的封装,类的继承相关
一.命令模式的现实场景
线人蔡良把一条信息封装到一个超市的饮料瓶盖中,习伟接到上级命令去执行一项秘密任务,任务的内容是到一家名为XX的超市购买一瓶饮料,并把饮料带回来給上级领导,上级领导拿到饮料后将瓶盖留下了。上级领导,破解瓶盖的信息后,带人捣毁了一个贩毒的团伙并将团伙全部抓获。
在上面的场景中,上级领导和线人蔡良通过饮料瓶盖互通信息,这个过程类似于设计模式中的命令模式。线人创建了一条命令,然后把这条命令封装到一个饮料瓶盖,通过习伟传递給上级领导,然后领导得到具体信息,并且这个信息的内容传递人习伟不知道,也不需要知道。
二.命令模式(Command Pattern)的定义
将一个请求封装成一个对象,从而让你能使用不同的请求把客户端参数化,对于请求排队或者记录请求日记,可以提供命令的撤销和恢复功能。
三.命令模式的类图
四.命令模式的四个角色
1.命令(Command)角色
该角色声明一个給具体命令类的抽象接口,定义需要执行的命令。现实场景中的瓶盖
2.具体命令(Concrte Command)角色
该角色定义一个接收者和行为之间的弱耦合,实现命令方法,并调用接收者的相应操作。现实场景中根据瓶盖信息,细化具体操作。
3.调用者(Invoker)角色
该角色负责调用命令对象的执行请求。现实场景中的线人蔡良
4.接收者(Receive)角色
该角色负责具体实施和执行一个请求。现实场景中的领导
五.命令模式的优缺点
命令模式中的优点
1.类间解耦
调用者和接收者之间没有任何依赖,调用者实现功能只需要调用Command中的execute()即可,不需要了解是哪个接收者来执行。
2.可扩展性
Command的子类非常容易扩展,而调用者Invoker和高层的模块Client不产生严重的代码耦合。
3.命令模式结合其他模式会跟优秀。
命令模式可以结合责任链模式,实现灵敏解析任务;
结合模板方法模式,可以减少Command子类的膨胀问题。
命令模式的缺点
使用命令模式可能会导致系统中出现过多的具体命令类,因此在项目中使用命令模式时需要慎重考虑。
六.命令模式的使用场景
1.使用命令模式作为“回调”在面向对象系统中的代替。“回调”就是将一个方法登记,方便在以后调用此方法。
2.需要在不同的时间指定请求、将请求排队。
3.系统需要支持命令的撤销(undo方法)。命令对象可以把状态存储起来,等到客户需要撤销时,可以调用undo()方法,将命令所产生的效果撤销。
4.需要将系统中所有的数据更新操作保存到日志里,以便在系统崩溃时,可以根据日志读回所有的数据更新命令,重新调用execute()方法一条一条执行这些命令,从而回复系统在崩溃前所做的数据更新。
5.一个系统需要支持交易。一个交易结构封装了一组数据更新命令。使用命令模式来实现交易结构可以使系统增加新的交易类型。
七.命令模式的示例
这里使用上面的现实常见做代码示例。
实例类图
实例代码
1.命令接口ICommand
package p14_command;
/**
* 命令接口
*/
public interface ICommand {
void execute();
}
2.具体命令
package p14_command;
/**
* 根据线人信息,制定具体命令
*/
public class AppointmentCommand implements ICommand {
//目标人姓名
private String name;
public AppointmentCommand(String name) {
this.name = name;
}
//线人提供的具体线索
@Override
public void execute() {
System.out.println("to "+name+":\n今天晚上8点,某贩毒集团在XX地点交易");
}
}
3.调用者类PersonInvoker
package p14_command;
/**
* 调用者类
* 持有命令接口对象
*/
public class PersonInvoker {
private ICommand command;
public void setCommand(ICommand command) {
this.command = command;
}
//执行命令
public void action() {
command.execute();
}
}
4.接收者类PersonRev
package p14_command;
/**
* 接收者类
*/
public class PersonRev {
private String name;
public PersonRev(String name) {
this.name = name;
}
public String getName() {
return name;
}
//接收者的行为
public void action() {
System.out.println("-----晚上8点," + name + " 带领部下销毁贩毒团队!");
}
}
5.测试类
package p14_command;
/**
* 测试类
*/
public class CommandDemo {
public static void main(String[] args) {
PersonInvoker personInvoker = new PersonInvoker();//调用者,线人
PersonRev leader = new PersonRev("XX领导");//接收者,领导
//创建命令,子类的实例化
ICommand command = new AppointmentCommand(leader.getName());
//调用者,封装信息
personInvoker.setCommand(command);
personInvoker.action();
//调用者执行后,领导才接收者的行为
leader.action();
}
}
程序运行结果;
命令模式模式就为大家介绍到这里。
大家如果对其他设计模式有兴趣可以看看我之前的博客:
13模板方法模式:http://blog.csdn.net/wenzhi20102321/article/details/79284870
12享元模式:http://blog.csdn.net/wenzhi20102321/article/details/78724677
11外观模式:http://blog.csdn.net/wenzhi20102321/article/details/78639087
10桥梁模式:http://blog.csdn.net/wenzhi20102321/article/details/78566532
9组合模式:http://blog.csdn.net/wenzhi20102321/article/details/78463190
8适配器模式:http://blog.csdn.net/wenzhi20102321/article/details/78389326
7装饰模式:http://blog.csdn.net/wenzhi20102321/article/details/78336273
6代理模式:http://blog.csdn.net/wenzhi20102321/article/details/78209493
创建型模式详解:http://blog.csdn.net/wenzhi20102321/article/details/78175558
5原型模式:http://blog.csdn.net/wenzhi20102321/article/details/78167984
4建造者模式:http://blog.csdn.net/wenzhi20102321/article/details/78163855
3抽象工厂模式:http://blog.csdn.net/wenzhi20102321/article/details/78153437
2工厂方法模式:http://blog.csdn.net/wenzhi20102321/article/details/78129065
可以仔细对比一下工厂方法模式和抽象工厂模式,看看概念,看看类图,看看代码,就会明白了。
1单例模式:http://blog.csdn.net/wenzhi20102321/article/details/77882203
java 23种设计模式介绍:http://blog.csdn.net/wenzhi20102321/article/details/54601909