设计模式(9):命令模式

来源:互联网 发布:java代码换行符 编辑:程序博客网 时间:2024/06/06 10:44

命令模式:

定义:

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

 

通用类图:

 

 

 

Receiver接受者角色:

该角色就是干活的角色,命令传递到这里是应该被执行的

Command命令角色

需要执行的所有命令都在这里声明

Invoker调用者角色

接收到命令并执行命令。

 

 

 

优缺点:

优点:

类间解耦

调用者角色与接受者角色之间没有任何依赖关系,调用者实现功能时只需要调用Command抽象类的execute方法就可以,不需要了解到底是哪个接受者执行

 

可扩展性

Command的子类可以非常容易的扩展,而调用者Invoker和高层次的Client不产生严重的代码耦合

 

命令模式结合其他模式会更优秀

命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少Command子类的膨胀问题。

 

缺点:

如果有N个命令,Command的子类就是N个,容易膨胀。

 

 

 

 

举个例子:

实现一个项目,该项目的成员分工采用了常规的分工方式:需求组、美工组、代码组

 

 

 

 

abstract class Group {public abstract void find();public abstract void add();public abstract void delete();public abstract void change();public abstract void plan();}// 需求组class RequirementGroup extends Group {public void find() {System.out.println("找到需求组---");}// 增加一项需求public void add() {System.out.println("客户要求增加一项需求---");}// 客户要求删除一项需求public void delete() {System.out.println("客户要求删除一项需求---");}public void change() {System.out.println("客户要求修改一项需求---");}public void plan() {System.out.println("客户要求变更计划---");}}// 美工组class PageGroup extends Group {public void find() {System.out.println("找到美工组---");}public void add() {System.out.println("客户要求增加一个页面---");}public void delete() {System.out.println("客户要求删除一个页面---");}public void change() {System.out.println("客户要求修改一个页面---");}public void plan() {System.out.println("客户要求页面变更计划---");}}class CodeGroup extends Group {public void find() {System.out.println("找到代码组---");}public void add() {System.out.println("客户要求增加一项功能---");}public void delete() {System.out.println("客户要求删除一项功能---");}public void change() {System.out.println("客户要求修改一项功能---");}public void plan() {System.out.println("客户要求代码变更计划---");}}public class Client {public static void main(String[] args) { System.out.println("----------客户要求增加一项需求----------"); Group rg = new RequirementGroup(); rg.find(); rg.add(); rg.plan();}}


 

 

 

 

 

在原有类图上增加了一个Invoker类,其作用是根据客户的命令安排不同的组员进行工作。但是在系统设计中,字符串没有约束力,根据字符串判断相关的业务逻辑不是一个优秀的解决方案。

解决方案是对客户发出的命令进行封装,每个命令是一个对象,避免客户、负责人、组员之间的交流误差,封装后的结果就是客户只要说一个命令,我的项目组就立刻开始启动,不用思考、解析命令字符串。

 

 

 

 

Command抽象类只有一个方法execute,其作用就是执行命令,子类非常坚决的解决该命令。

 

Command抽象类:客户发给我们的命令,定义三个工作组的成员变量,供子类使用;定义一个抽象方法execute,由子类实现。

 

Invoker实现类:项目接头负责人,setCommand接收客户发给我们的命令,action方法是执行客户的命令

 

 

抽象命令类:

 

abstract class Command {protected RequirementGroup rg = new RequirementGroup();protected PageGroup pg = new PageGroup();protected CodeGroup cg = new CodeGroup();public abstract void execute();}


 

需要什么功能就 继承该类,并实现execute方法

 

 

增加需求:

 

// 增加需求的命令class AddRequirementCommand extends Command {// 执行增加一项需求的命令public void execute() {super.rg.find();super.rg.add();super.rg.plan();}}


 

删除一个页面:

 

class DeletePageCommand extends Command {// 执行删除一个页面的命令public void execute() {super.pg.find();super.pg.delete();super.pg.plan();}}


 

Invoker类:

class Invoker {private Command command;public void setCommand(Command _command) {this.command = _command;}// 执行客户的命令public void action() {this.command.execute();}}

 

增加一个需求Client:

 

public class Client {public static void main(String[] args) {Invoker invoker = new Invoker();System.out.println("-------客户要求增加一项需求---------");Command command = new AddRequirementCommand();invoker.setCommand(command);invoker.action();}}



 

删除一个页面Client:

 

public class Client {public static void main(String[] args) {Invoker invoker = new Invoker();System.out.println("-------客户要求增加一项需求---------");//Command command = new AddRequirementCommand();Command command = new DeletePageCommand();invoker.setCommand(command);invoker.action();}}


 

只需要修改很少就可以实现功能的转变。

0 0
原创粉丝点击