在此之前推荐一本设计模式书籍,个人认为很不错,很经典的一本书,《设计模式之禅》,分享给希望了解设计模式相关知识的朋友。
下载地址: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,实现满足客户基本需求。
1、客户不断提出需求,需要找三个组来解释,他烦不烦?
2、面对同一个需求,三个组要分别于客户交流,组员累不累?
如果你是客户,是不是更希望有这样一种情况:我提出一个要求(command),我不需要去管你们内部三个组(Group)如何实现,我只要命令发出去,我要的是结果。是不是这才是客户真正需要的?哈哈,考虑到用户体验这块,客户希望越方便越好。
那接下来如何调整,看第二张图:
Command抽象类,来自客户的需求,定义了三个不同组的成员变量,定义了一个抽象execute方法
比如增加需求的一个命令,一个很常见的命令,具体这么来写;
增加需求命令.....
找到需求组
需求组增加一个需求
第二个删除页面命令同类似 ,该成Command command = new DeletePageCommand() 即可,这样下来是不是很方便了呢?
客户来一个命令,只要实现一个对应的命令即可,客户端只要改一句即可,这样的设计满足了客户端代码尽量少的原则。
思考:1、好处在哪里?
2、很完美么?是否还有缺陷
命令模式的定义是这样的,讲客户的一个请求封装成一个对象,从而将不同的请求把客户端参数化
在上面的例子中定义了三种角色
1.Group类 (接收者角色)也就是具体干活的角色
2.Command类 (命令) 需要执行的命令继续这个类,指定接收者角色就可以。
3.Invoker类(调用者角色)接收到命令后,执行该命令。
以上是我的个人理解,不足之处还希望众友多多提出,不胜感激!
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)如何实现,我只要命令发出去,我要的是结果。是不是这才是客户真正需要的?哈哈,考虑到用户体验这块,客户希望越方便越好。
那接下来如何调整,看第二张图:
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类(调用者角色)接收到命令后,执行该命令。
以上是我的个人理解,不足之处还希望众友多多提出,不胜感激!