天天看点

【设计模式十五之命令模式】命令模式细说命令模式

Command Pattern 命令模式

  • 细说命令模式
    • 细说命令模式
      • 定义
      • UML模型
      • 场景
        • 场景一
        • 场景二
      • 代码
        • 代码一
        • 代码二
        • 基于UML的代码
      • 命令模式应用和注意事项

细说命令模式

提示:

博主:章飞 _906285288的博客

博客地址:http://blog.csdn.net/qq_29924041

细说命令模式

定义

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

命令模式其实是将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可提供命令的撤销和恢复功能。

所以其实命令模式就是将命令具体化。每个命令下,所对应的响应者根据命令类型来进行做出相应的行为。

UML模型

【设计模式十五之命令模式】命令模式细说命令模式

从UML图中看出命令模式主要分为以下几种角色类型:

1:Conmmand 命令接口,即所有要执行的命令都需要在这里去声明

2:ConcreteCommand 具体的命令类型。实现Command接口

3:Receiver 命令的接受者类型。该角色其实是干活的,命令传递到这里的时候,需要Receiver去执行命令

4:Invoker 命令的调用者类型。也就是发号命令的类,持有命令对象,要求命令对象执行请求

场景

场景一

来自设计模式之禅中的案例,现在做一个项目,项目大组内又分为三个项目小组,有需求组,有代码组,有UI组。有个项目经理,作为外部对接以及内部项目把控,调节的对象。当外部需要做一个需求变更的时候,这个时候需要对告诉项目经理,由项目经理去发号施令,调度内部的几个项目组同事进行修改。在这个模型中,项目经理其实就是invoker,内部的几个项目组是receiver,而调度的过程则为命令类型。

场景二

上过初中以上的人基本上都参加过入学军训吧。一个教官带一个班级,夏天站在操场上军训,现在回想来,也已经好多年了啊。军训的时候,教官有一系列的命令,比如向右看齐 向前看 稍息 立正 稍息,向左转,齐步走,跑步走等等。每个学员在得到相应命令的时候,都要立马切换相应动作。做错了要被夯的啊。这个模型中,教官其实就是invoker,学员则为receiver,一系列的命令则是一个个的Command实例对象。

代码

代码一

定义抽象的组类型,每个内部项目组都需要实现

package src.com.zzf.designpattern.commandpattern.demo1;


public abstract class Group {
	//与项目组协调
	public abstract void find();
	//增加功能
	public abstract void add();
	//删除功能
	public abstract void delete();
	//修改功能
	public abstract void change();
	//变更计划
	public abstract void plan();
	
}


           

UI组

package src.com.zzf.designpattern.commandpattern.demo1;


public class PageGroup extends Group{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("PageGroup add");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("PageGroup delete");
	}

	@Override
	public void change() {
		// TODO Auto-generated method stub
		System.out.println("PageGroup change");
	}

	@Override
	public void find() {
		// TODO Auto-generated method stub
		System.out.println("PageGroup find");
	}

	@Override
	public void plan() {
		// TODO Auto-generated method stub
		System.out.println("PageGroup plan");
	}

}

           

代码组

package src.com.zzf.designpattern.commandpattern.demo1;


public class CodeGroup extends Group{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("CodeGroup add");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("CodeGroup delete");
	}

	@Override
	public void change() {
		// TODO Auto-generated method stub
		System.out.println("CodeGroup change");
	}

	@Override
	public void find() {
		// TODO Auto-generated method stub
		System.out.println("CodeGroup find");
	}

	@Override
	public void plan() {
		// TODO Auto-generated method stub
		System.out.println("CodeGroup plan");
	}

}

           

需求组

package src.com.zzf.designpattern.commandpattern.demo1;


public class RequirementGroup extends Group{

	@Override
	public void add() {
		// TODO Auto-generated method stub
		System.out.println("RequirementGroup add");
	}

	@Override
	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("RequirementGroup delete");
	}

	@Override
	public void change() {
		// TODO Auto-generated method stub
		System.out.println("RequirementGroup change");
	}

	@Override
	public void find() {
		// TODO Auto-generated method stub
		System.out.println("RequirementGroup find");
	}

	@Override
	public void plan() {
		// TODO Auto-generated method stub
		System.out.println("RequirementGroup plan");
	}

}

           

抽象的命令类型

package src.com.zzf.designpattern.commandpattern.demo1;


public abstract class Command {
	CodeGroup cg = new CodeGroup();
	PageGroup pg = new PageGroup();
	RequirementGroup rGroup = new RequirementGroup();
	
	
	public abstract void excuteCommand();
}

           

删除页面的命令类型

package src.com.zzf.designpattern.commandpattern.demo1;


public class DeletePageCommand extends Command{

	@Override
	public void excuteCommand() {
		// TODO Auto-generated method stub
		super.pg.find();
		super.pg.delete();
		super.pg.plan();
	}

}

           

增加需求的命令类型

package src.com.zzf.designpattern.commandpattern.demo1;


public class AddRequirementCommand extends Command{

	@Override
	public void excuteCommand() {
		// TODO Auto-generated method stub
		super.rGroup.find();
		super.rGroup.add();
		super.rGroup.change();
		super.rGroup.plan();
	}

}

           

测试类型

package src.com.zzf.designpattern.commandpattern.demo1;


/**
 * 命令模式是在软件开发过程中使用相对比较频繁的一种模式,它主要有三个要素
 * Invoker 调用者,接收到命令,并执行命令,例子中我这里项目经理就是这个角色;
 * Command(abstract) 就是命令,需要我执行的所有命令都这里声明;
 * Receiver  这个就是干活的角色,命令传递到这里是应该被执行的,具体到上面我们的例子中就是Group 的三个实现类;
 * @author Administrator
 * 命令模式其实是将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可提供命令的撤销和恢复功能
 *
 */
public class ComandPatternTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Command mCommand = new AddRequirementCommand();
		Invoker mInvoker = new Invoker();
		mInvoker.setCommand(mCommand);
		mInvoker.excuteCommand();
	}

}

           

代码二

定义军训的学生

package src.com.zzf.designpattern.commandpattern.demo3;

public class Student {
	//立正
	public void  actionStandAtAttention() {
		System.out.println("军训学员立正");
	}
	
	//稍息
	public void  actionStandAtEase() {
		System.out.println("军训学员稍息");
	}
}

           

定义抽象命令

package src.com.zzf.designpattern.commandpattern.demo3;

public abstract class Command {
	Student student = new Student();
	
	public abstract void excute();
}

           

定义一个军训教官

package src.com.zzf.designpattern.commandpattern.demo3;

import src.com.zzf.designpattern.commandpattern.demo3.Command;

public class ArmyInstructor {
	Command mCommand = null;
	
	public void setCommand(Command mCommand){
		this.mCommand = mCommand;
	}
	
	public void excute(){
		this.mCommand.excute();
	}
}

           

定义具体的命令类型,立正命令类型

package src.com.zzf.designpattern.commandpattern.demo3;

public class StandAtAttentionCommand extends Command{

	@Override
	public void excute() {
		// TODO Auto-generated method stub
		student.actionStandAtAttention();
	}

}

           

定义稍息命令

package src.com.zzf.designpattern.commandpattern.demo3;

public class StandAtEaseCommand extends Command{

	@Override
	public void excute() {
		// TODO Auto-generated method stub
		student.actionStandAtEase();
	}

}

           

测试代码

package src.com.zzf.designpattern.commandpattern.demo3;

import src.com.zzf.designpattern.commandpattern.demo2.ConcreteCommand;
import src.com.zzf.designpattern.commandpattern.demo2.Invoker;

public class Test {
	public static void main(String[] args) {
		ArmyInstructor mInvoker = new ArmyInstructor();
		mInvoker.setCommand(new StandAtAttentionCommand());
		mInvoker.excute();
		mInvoker.setCommand(new StandAtEaseCommand());
		mInvoker.excute();
	}
}

           

基于UML的代码

package src.com.zzf.designpattern.commandpattern.demo2;


public abstract class Command {
	public abstract void excute();
}

           
package src.com.zzf.designpattern.commandpattern.demo2;


public class ConcreteCommand extends Command{

	Receiver mReceiver = new Receiver();
	
	@Override
	public void excute() {
		// TODO Auto-generated method stub
		mReceiver.action();
	}

}

           
package src.com.zzf.designpattern.commandpattern.demo2;


public class Invoker {
	Command mCommand = null;
	
	public void setCommand(Command mCommand){
		this.mCommand = mCommand;
	}
	
	public void excute(){
		this.mCommand.excute();
	}
}

           
package src.com.zzf.designpattern.commandpattern.demo2;


public class Receiver {

	public void action() {
		System.out.println("收到命令,执行操作");
	}
}

           
package src.com.zzf.designpattern.commandpattern.demo2;


/**
 * 命令模式三要素
 * Invoker
 * Receiver
 * Command
 * @author Administrator
 *
 */
public class InvokerTest {
	public static void main(String[] args) {
		Invoker mInvoker = new Invoker();
		mInvoker.setCommand(new ConcreteCommand());
		mInvoker.excute();
	}
}

           

命令模式应用和注意事项

命令模式中调用者角色和接收者角色之间是没有任何依赖关系的,调用者实现功能时只要调用Command类中的执行方法就可以,不需要了解到是哪个接受者

命令模式具有很好的扩展性,如果需要添加一个命令,可以直接继承Command类,则可以直接可以扩展

欢迎继续访问,我的博客