行为型模式 | 命令模式解析及应用

一、定义

命令模式:将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。
(命令模式是一种对象行为型模式,其别名为动作模式或事务模式.)

命令模式的本质是:对命令进行封装,将发出命令的责任与执行命令的责任分割开。

二、特点

优点:

  • 类间解耦:调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command 抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。
  • 可扩展性:Command的子类可以非常容易地扩展,增加新的命令很方便。
  • 可以比较容易设计一个命令队列和宏命令,并方便地实现对请求的撤销和恢复
  • 命令模式结合其他模式:命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少 Command子类的膨胀问题等

缺点:

  • 可能会导致某些系统有过多的具体命令类。如:有N个命令,Command的子类就不是几个,而是N个,这点需要在项目中考虑使用。

模式扩展:
宏命令又称为组合命令,它是命令模式和组合模式联用的产物。
宏命令也是一个具体命令,不过它包含了对其他命令对象的引用,在调用宏命令的execute()方法时,将递归调用它所包含的每个成员命令的execute()方法,一个宏命令的对象成员可以是简单命令,还可以继续是宏命令。执行一个宏命令将执行多个具体命令,从而实现对命令的批处理。

三、使用场景

以下情况可以使用职责链模式:

  • 需要将请求调用者与请求接收者解耦,使得调用者和接收者不直接交互
  • 需要在不同时间指定请求、请求排队和执行请求。
  • 需要支持命令的撤销操作和恢复操作
  • 需要将一组操作组合在一起,即支持宏命令。

四、类图

在这里插入图片描述
角色:
Command:抽象命令类
ConcreteCommand: 具体命令类
Invoker:调用者
Receiver:接受者
Client:客户类

五、实战代码

将水果订单封装成命令对象并调用执行

【Command.java】

package command;

public interface Command {
	void execute();    //声明一个执行方法

}

【OrderCommand .java】

package command;

public class OrderCommand implements Command {
	private Operator receiver;
	private Order order;
	//放两个参数,一个是执行者,一个是执行的目标
	public OrderCommand(Operator receiver,Order order){
		this.receiver =receiver;
		this.order=order;
	}
	
	public void execute() {
		// TODO Auto-generated method stub
        System.out.println(order.getId()+" 号顾客的成品");
	    receiver.MarkFuit(order);
	}

}

【Order.java】

package command;

import java.util.HashMap;

public class Order {

	private int id;
	private HashMap<String,Integer> fruitmap;
	public Order(){
		fruitmap=new HashMap<String,Integer> ();
		
	}
	public int getId() {
		// TODO Auto-generated method stub
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public HashMap<String,Integer> getFruitmap() {
		return fruitmap;
	}
	public void setFruitmap(String fruitkind,int quantity) {
		this.fruitmap.put(fruitkind, quantity);
	}

}

【Waitor_Invoker.java】

package command;

import java.util.ArrayList;

public class Waitor_Invoker {
	private ArrayList<Command> commands=null;
	public Waitor_Invoker(){
		commands=new ArrayList<Command>();
		
	}
	public void setCommand(Command cmd){
		commands.add(cmd);
	}
	public void OrderUp(){
		System.out.println("有订单");
		for(Command cmd:commands){
			if(cmd!=null)
				cmd.execute();
		}
	}
}

【Operator.java】

package command;

public class Operator {

	public void MarkFuit(Order order) {
		// TODO Auto-generated method stub
		String str="";
		for(String key:order.getFruitmap().keySet()){
			str+=key+order.getFruitmap().get(key);
		}
		System.out.println("黑暗混合汁:"+str);
	}

}

【ClientClass.java】

package command;

public class ClientClass {

	public static void main(String[] args) {
		//创建多个订单
		Order order1=new Order();
		order1.setId(1);
		order1.setFruitmap("橙子", 1);
		order1.setFruitmap("梨子", 2);
		order1.setFruitmap("苹果", 3);

		Order order2=new Order();
		order2.setId(2);
		order2.setFruitmap("香蕉", 4);
		order2.setFruitmap("葡萄", 2);
		order2.setFruitmap("西红柿", 3);
		//创建操作者
		Operator op=new Operator();
		//将多个订单封装成命令对象
		OrderCommand cmd1=new OrderCommand(op,order1);
		OrderCommand cmd2=new OrderCommand(op,order2);

		//创建调用者并加命令进去
		Waitor_Invoker waitor=new Waitor_Invoker();
		waitor.setCommand(cmd1);
		waitor.setCommand(cmd2);

		//执行命令
		waitor.OrderUp();
	}

}

【运行截图】

在这里插入图片描述


喜欢的话记得点赞收藏哟😊
Java设计模式—博文专栏持续更新!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大雄不是大熊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值