命令模式

命令模式
简介:它将请求发送者,请求接收者解耦,可以让相同的发送者对应不同的接收者。
命令模式定义:将一个请求封装成一个对象,从而通过不同的请求将客户端参数化,实现了请求排队,记录请求日志,可撤销操作
案例:烧烤摊和烧烤店

public class Command {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Barbecuer boy =new Barbecuer();
		boy.BakeMutton();
		boy.BakeChickWing();
	}

}
class Barbecuer{
	//烤羊肉
	public void BakeMutton()
	{
		System.out.println("烤羊肉串!");
	}
	//烤鸡翅
	public void BakeChickWing()
	{
		System.out.println("烤鸡翅!");
	}
}

问题:店主直接与消费者对话,耦合性太高,店主需要实现的功能过度
解决:引进服务者类,成为店长和消费者之间沟通的桥梁
在这里插入图片描述

public class Command1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Barbecuer boy = new Barbecuer();
		Commands command1=new  BakeMuttonCommand(boy);
		Commands command2=new  BakeChickenWingCommand(boy);
		Commands command3=new  BakeChickenWingCommand(boy);
	    Waiter girl=new Waiter();
	    //开业
	    girl.SetOrder(command1);
	    girl.Notify();
	    girl.SetOrder(command2);
	    girl.Notify();
	    girl.SetOrder(command3);
	    girl.Notify();
	}

}

class Barbecuer{
	public void BakeMutton()
	{
		System.out.println("烤羊肉串!");
	}
	//烤鸡翅
	public void BakeChickWing()
	{
		System.out.println("烤鸡翅!");
	}
}
abstract class Commands {// 声明执行的接口
	protected Barbecuer receiver;

	public Commands(Barbecuer receiver) {
		super();
		this.receiver = receiver;
	}
	//执行命令
	public abstract void ExcuteCommand();
}
//烤羊肉串命令
class BakeMuttonCommand extends Commands{

	public BakeMuttonCommand(Barbecuer receiver) {
		super(receiver);
		// TODO Auto-generated constructor stub
	}


	@Override
	public void ExcuteCommand() {
		// TODO Auto-generated method stub
		this.receiver.BakeMutton();
	}
	
}
class BakeChickenWingCommand extends Commands{

	public BakeChickenWingCommand(Barbecuer receiver) {
		super(receiver);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void ExcuteCommand() {
		// TODO Auto-generated method stub
		this.receiver.BakeChickWing();
	}
	
}
class Waiter{//服务员类
	//增加存放具体命令的容器
	private Commands command;
	
	//设置订单
	public void SetOrder(Commands command)
	{
		this.command=command;
	}
	//通知执行
	public void Notify()
	{
		command.ExcuteCommand();
	}
}

服务员只能记住一个命令,不符合实际情况
改进:使用链表

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

public class Command2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Barbecuer boy = new Barbecuer();
		Commands command1=new  BakeMuttonCommand(boy);
		Commands command2=new  BakeChickenWingCommand(boy);
		Commands command3=new  BakeChickenWingCommand(boy);
	    Waiter girl=new Waiter();
	    //开业点餐
	    girl.SetOrder(command1);
	    girl.SetOrder(command2);
	    girl.SetOrder(command3);
	    
	    //通知厨房
	    
	    girl.Notify();
	}

}

class Barbecuer{
	public void BakeMutton()
	{
		System.out.println("烤羊肉串!");
	}
	//烤鸡翅
	public void BakeChickWing()
	{
		System.out.println("烤鸡翅!");
	}
}
abstract class Commands {// 声明执行的接口
	protected Barbecuer receiver;

	public Commands(Barbecuer receiver) {
		super();
		this.receiver = receiver;
	}
	//执行命令
	public abstract void ExcuteCommand();
}
//烤羊肉串命令
class BakeMuttonCommand extends Commands{

	public BakeMuttonCommand(Barbecuer receiver) {
		super(receiver);
		// TODO Auto-generated constructor stub
	}


	@Override
	public void ExcuteCommand() {
		// TODO Auto-generated method stub
		this.receiver.BakeMutton();
	}
	
}
class BakeChickenWingCommand extends Commands{

	public BakeChickenWingCommand(Barbecuer receiver) {
		super(receiver);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void ExcuteCommand() {
		// TODO Auto-generated method stub
		this.receiver.BakeChickWing();
	}
	
}
class Waiter{//服务员类
	//增加存放具体命令的容器
	private List commands =new ArrayList<Commands>();
	
	//设置订单
	public void SetOrder(Commands command)
	{
		if(command.getClass().getName().equals("org.zangyu.Command.BakeChickenWingCommand"))
		{
			System.out.println("服务员:鸡翅没了");
		}else
		{
			commands.add(command);
			SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			//设置日期格式
			//记录日志,以备结账,new date()获取当前系统时间
			System.out.println("增加订单:"+command.getClass().getName()+"时间:"+df.format(new Date()));
		}
	}
	//取消订单
	public void CancelOrder(Commands command)
	{
		commands.remove(command);
		SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//设置日期格式
		//记录日志,以备结账,new date()获取当前系统时间
		System.out.println("取消订单:"+command.getClass().getName()+"时间:"+df.format(new Date()));
	}
	//通知执行
	public void Notify()
	{
		Iterator <Commands> cmd = commands.iterator();
		while(cmd.hasNext()) {
			cmd.next().ExcuteCommand();
		}
	}
}

命令模式基本框架——源代码

public class Command3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
    Receiver r =new Receiver();
    Commands c=new ConcreteCommand(r);
    Invoker i =new Invoker();
    
    
    i.setCommands(c);
    i.ExecuteCommand();
    
	}

}
class Receiver
{
	public void Action()
	{
		System.out.println("执行命令");
	}
}
//用来声明执行的命令的接口
abstract class Commands
{
	protected Receiver receiver;

	public Commands(Receiver receiver) {
		super();
		this.receiver = receiver;
	}
	
	abstract public void Execte();
}
//具体命令类
class ConcreteCommand extends Commands
{

	public ConcreteCommand(Receiver receiver) {
		super(receiver);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void Execte() {
		// TODO Auto-generated method stub
		receiver.Action();
	}
	
}
//要求该命令执行这个请求
class Invoker
{
	private Commands commands;

	public Commands getCommands() {
		return commands;
	}

	public void setCommands(Commands commands) {
		this.commands = commands;
	}
	public void ExecuteCommand()
	{
		commands.Execte();
	}
}

优点:

1.类间解耦:调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command 抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。
2.可扩展性:Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模块Client不产生严 重的代码耦合。
3.命令模式结合其他模式会更优秀:命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少 Command子类的膨胀问题。
缺点:
命令模式也是有缺点的,请看Command的子类:如果有N个命令,问题就出来 了,Command的子类就可不是几个,而是N个,这个类膨胀得非常大,这个就需要读者在项 目中慎重考虑使用。

使用时机:

当需要先将一个函数登记上,然后再以后调用此函数时,就需要使用命令模式,其实这就是回调函数。

有时候需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是什么。此时希望用一种松耦合的方式来设计程序,使得请求发送者和请求接收者能够消除彼此之间的耦合关系

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值