设计模式(九)—命令模式
最后更新于:2022-04-01 16:26:11
**定义**:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,
可以提供命令的撤销和恢复功能。
## 命令模式的通用模式:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_5755340a10f29.jpg)
**该类图中**
Receive接受者角色
---|该角色就是干活的角色,命令传递到这里应该是被执行的
Command命令角色
---|需要执行的所有命令都在这里声明
Invoker调用者角色
---|接收命令,并执行命令。
~~~
public class CommandTest {
public static void main(String[] args) {
//首先声明调用者Invoker
MyInvoker invoker = new MyInvoker();
//声明命令的接收者
Receiver receiver1 = new ConcreteReceive1();
//声明命令
Command command1 = new ConcreteCommand1(receiver1);
invoker.setCommand(command1);
invoker.action();
}
}
abstract class Receiver{
//抽象的接收者,定义具体接受者要实现的方法
public abstract void doSomething();
}
class ConcreteReceive1 extends Receiver{
@Override
public void doSomething() {
System.out.println("接收者1号,需要执行的方法....");
}
}
class ConcreteReceiver2 extends Receiver{
@Override
public void doSomething() {
System.out.println("接收者2号,需要执行的方法...");
}
}
abstract class Command{
//抽象的命令类,定义要执行的命令,具体命令主体由子类来完成。
public abstract void execute();
}
class ConcreteCommand1 extends Command{
private Receiver receiver;
//用构造函数来传递,具体的接收者是谁。
public ConcreteCommand1(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
//让接收者去执行具体的方法。
this.receiver.doSomething();
}
}
class ConcreteCommand2 extends Command{
private Receiver receiver;
//用构造函数来传递,具体的接收者是谁。
public ConcreteCommand2(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
//让接收者去执行具体的方法。
this.receiver.doSomething();
}
}
class MyInvoker{
private Command command;
//调用者角色,去决定具体的接收者执行什么命令
public void setCommand(Command command) {
this.command = command;
}
public void action() {
this.command.execute();
}
}
~~~
## 一个例子:
一个项目组分为需求组(require),美工组,编码组,三部分。客户在进行修改需求、美工时需要对各个部门进行交互。
但是这样的做法对客户来说十分不便捷。因此需要一个中介者替客户传达他对各项目组的需求。
他将客户一系列的命令(Command)传达给不同的项目小组。
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-06-06_5755340a2ec27.jpg)
~~~
public class CommandEx {
public static void main(String[] args) {
//首选创建一个指挥者实体
Invoker invok = new Invoker();
//命令实体要求添加一个需求
CommandWork cw1 = new AddRequire();
CommandWork cw2 = new DelPage();
//指挥者,设置好命令
invok.addCommand(cw1);
invok.addCommand(cw2);
//指挥者去传达命令。
invok.action();
}
}
abstract class GroupWork{
/**
* 抽象的项目工作类,定义需要的方法供实现类去执行。
*/
//找具体的执行者
public abstract void find();
//要求添加功能
public abstract void add();
//要求删除功能
public abstract void delete();
//要求修改功能
public abstract void change();
//要求制定出具体的计划
public abstract void plan();
}
/**
* 美工组,执行任务
* @author admin
*
*/
class PageGroup extends GroupWork{
@Override
public void find() {
System.out.println("找到美工组....");
}
@Override
public void add() {
System.out.println("要求美工组添加一张图片...");
}
@Override
public void delete() {
System.out.println("要求美工组删除一张图片....");
}
@Override
public void change() {
System.out.println("要求美工组修改这张页面....");
}
@Override
public void plan() {
System.out.println("要求美工组制定出具体计划....");
}
}
/*
* 编码组,执行任务
*/
class CodeGroup extends GroupWork{
@Override
public void find() {
System.out.println("找到程序员....");
}
@Override
public void add() {
System.out.println("要求程序员添加一个绚丽的功能...");
}
@Override
public void delete() {
System.out.println("要求程序员删除有bug的功能....");
}
@Override
public void change() {
System.out.println("要求程序员修改具体功能....");
}
@Override
public void plan() {
System.out.println("要求程序员制定出详细的计划....");
}
}
/**
* 需求组执行任务。
* @author admin
*
*/
class requireGroup extends GroupWork{
@Override
public void find() {
System.out.println("找到需求组....");
}
@Override
public void add() {
System.out.println("要求需求组添加一项功能...");
}
@Override
public void delete() {
System.out.println("要求需求组删除项功能....");
}
@Override
public void change() {
System.out.println("要求美需求组修改一项....");
}
@Override
public void plan() {
System.out.println("要求需求组制定详细的需求分析....");
}
}
abstract class CommandWork{
/**
* 模拟客户提出要求,并且让具体的项目组去执行任务。
*/
//这里已经知道这三类项目小组,所以在抽象类中直接实例化
GroupWork rg = new requireGroup();
GroupWork pg = new PageGroup();
GroupWork cg = new CodeGroup();
public abstract void executeWork();
}
class AddRequire extends CommandWork{
@Override
public void executeWork() {
//找到需求组
super.rg.find();
//添加一个功能
super.rg.add();
//指定具体计划
super.rg.plan();
}
}
class DelPage extends CommandWork{
@Override
public void executeWork() {
//找到需求组
super.pg.find();
//添加一个功能
super.pg.delete();
//指定具体计划
super.rg.plan();
}
}
class Invoker{
/**
* 命令的调用者,通过该类,向项目组传达客户的命令。
* 相当于项目经理。
*/
private ArrayList<CommandWork> command_list = new ArrayList<CommandWork>();
public void addCommand(CommandWork command){
this.command_list.add(command);
}
public void action(){
if(command_list.size()>0){
for(CommandWork cw : command_list){
cw.executeWork();
}
}
/*//接收到命令,就去转达
this.cw.executeWork();*/
}
}
~~~
**命令模式的优点:**
* 类间解耦
* 可扩展性
* 命令模式结合其他模式更优秀