命令模式

    在此之前推荐一本设计模式书籍,个人认为很不错,很经典的一本书,《设计模式之禅》,分享给希望了解设计模式相关知识的朋友。

    下载地址:http://download.csdn.net/detail/cherishme1988/6319299

命令模式 --command,维基百科上的解释是这样的,http://zh.wikipedia.org/wiki/%E5%91%BD%E4%BB%A4%E6%A8%A1%E5%BC%8F

面向对象程式设计的范畴中,命令模式是一种设计模式,它尝试以物件来代表实际行动。命令物件可以把行动(action) 及其参数封装起来,于是这些行动可以被:

  • 重复多次
  • 取消(如果该物件有实作的话)
  • 取消后又再重做

这些都是现代大型应用程式所必须的功能,即“复原”及“重复”。

那书中的例子来更好的理解下:场景1、客户有个项目需要交给一个团队开发,团队分工为客户需求组(RequirementGroup),美工组(PageGroup),代码开发组(CodeGroup)。刚开始,客户很乐意和每个组探讨,讨论具体需求,页面具体需求以及代码讨论实现,告诉他们修改,增加,删除等要求。这是一种很常见的甲乙合作模式。

可以使用一个类图来表示此过程。


   首先定义个抽象类Group,实现满足客户基本需求。
public abstract class   Group {
	public  abstract void find() ;
	public  abstract void add() ;
	public abstract  void delete() ;
	public abstract void update() ;
}
接下来就是分别定义三个组来实现不同的需求,CodeGroup、RequirementGroup、PageGroup
public class CodeGroup extends Group {
	public void find() {
		System.out.println("找到代码组");
	}
	public void add() {
		System.out.println("代码组增加需求") ;
	}
	public void delete() {
		System.out.println("代码组删除需求") ;
	}
	public void update() {
		System.out.println("代码组修改需求") ;
	}
}
public class RequeirmentGroup extends Group {
	public void find() {
		System.out.println("找到需求组")  ;
	}
		public void add() {
		System.out.println("需求组增加一个需求") ;
	}
	public void delete() {
		System.out.println("需求组删除一个需求") ;
	}
	public void update() {
		System.out.println("需求组修改一个需求") ;
	}
}
public class PageGroup  extends Group{
	public void find() {
		System.out.println("找到美工组") ;
	}
	public void add() {
		System.out.println("美工组增加一个页面");
	}
	public void delete() {
		System.out.println("美工组删除一个页面") ;
	}
	public void update() {
		System.out.println("美工组修改一个页面") ;
	}
}
好了,定义好三个实现类之后就可以具体接受客户的需求,场景1、假如说客户有一个修改一个页面需求,那代码应该这样来实现:
public class Client {
	public static void main(String[] args) {
		Group group = new PageGroup() ;
		group.find() ;   //找到页面组
		group.update() ;  //提出修改页面的需求;
	}
}
场景2、客户又增加了一个功能需求,需要找到需求分析组RequirementGroup,那改吗应该这么来;
public class Client {
	public static void main(String[] args) {
		Group group = new RequeirmentGroup() ;
		group.find() ;   //找到需求组
		group.add() ;  //添加新提出的需求;
	}
}
思考问题:
       1、客户不断提出需求,需要找三个组来解释,他烦不烦?
       2、面对同一个需求,三个组要分别于客户交流,组员累不累?
如果你是客户,是不是更希望有这样一种情况:我提出一个要求(command),我不需要去管你们内部三个组(Group)如何实现,我只要命令发出去,我要的是结果。是不是这才是客户真正需要的?哈哈,考虑到用户体验这块,客户希望越方便越好。
那接下来如何调整,看第二张图:


Command抽象类,来自客户的需求,定义了三个不同组的成员变量,定义了一个抽象execute方法
public abstract  class Command {
	CodeGroup cg = new CodeGroup() ;
	PageGroup pg = new PageGroup() ;
	RequeirmentGroup rg = new RequeirmentGroup() ;
	public   abstract void execute() ;
}
Invoker实现类,是命令负责人,来接受命令,定义了一个setCommand用户接受用户命令,定义一个action方法来实现命令,具体谁来实现,交给具体的命令调用者,我负责的只是传达命令。
public class Invoker {
	private Command command ;
	public void setCommand(Command command) {
		this.command = command;
	}
	public void action(){
		this.command.execute() ;
	}
}
接下来就是具体的命令,由具体的组员实现类来完成。
比如增加需求的一个命令,一个很常见的命令,具体这么来写;
public class AddRequeirmentCommand extends Command {
	public void execute() {
		System.out.println("增加需求命令.....");
		super.rg.find();   //找到需求组
		super.rg.add() ;  //添加新的需求 ;
	}
}
再比如删除页面命令:
public class DeletePageCommand extends Command {
	public void execute() {
		System.out.println("删除页面命令.....");
		super.pg.find() ;
		super.pg.delete() ;
	}
}
接下来我们完成第一个命令,写一个Client来实现以上需求;
public class Client {
	public static void main(String[] args) {
		Invoker invoker = new Invoker() ;   //找到一个负责人 ;
		Command command = new AddRequeirmentCommand() ;   //客户提出一个增加需求的命令;
		invoker.setCommand(command);  // 负责人接收客户的命令
		invoker.action() ;  //负责人将命令传达
	}
}
可以看到后台输出这样的结果;
增加需求命令.....
找到需求组
需求组增加一个需求

第二个删除页面命令同类似 ,该成Command command = new DeletePageCommand() 即可,这样下来是不是很方便了呢?
客户来一个命令,只要实现一个对应的命令即可,客户端只要改一句即可,这样的设计满足了客户端代码尽量少的原则。

思考:1、好处在哪里?
            2、很完美么?是否还有缺陷

命令模式的定义是这样的,讲客户的一个请求封装成一个对象,从而将不同的请求把客户端参数化
在上面的例子中定义了三种角色
1.Group类 (接收者角色)也就是具体干活的角色
2.Command类 (命令) 需要执行的命令继续这个类,指定接收者角色就可以。
3.Invoker类(调用者角色)接收到命令后,执行该命令。


以上是我的个人理解,不足之处还希望众友多多提出,不胜感激!




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值