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类,则可以直接可以扩展
欢迎继续访问,我的博客