设计模式

设计模式之禅-命令模式

2020-12-25  本文已影响0人  凉快先生

1.业务场景

为一家旅行社建立一套内部管理系统,管理他的客户、旅游资源、票务以及内部管理。这个项目的成员分工也是采用了常规的分工方式,分为需求组(RG),美工组(PG),代码组(CG)

2.项目组分成了三个组,每个组还是要接受增删改的命令

public abstract class Group {

//甲乙双方分开办公,你要和那个组讨论,你首先要找到这个组

public abstract void find();

//被要求增加功能

public abstract void add();

//被要求删除功能

public abstract void delete();

//被要求修改功能

public abstract void change();

//被要求给出所有的变更计划

public abstract void plan();

}

抽象类中的每个方法,是不是每个都是一个命令?找到它,增加,删除,给我计划!是不是命令,这也就是命令模式中的命令接收者角色(Receiver)。

3.需求组的职责是和客户谈定需求,这个组的人应该都是业务领域专家

public class RequirementGroup extends Group {

//客户要求需求组过去和他们谈

public void find() {

System.out.println("找到需求组...");

}

//客户要求增加一项需求

public void add() {

System.out.println("客户要求增加一项需求...");

}

//客户要求修改一项需求

public void change() {

System.out.println("客户要求修改一项需求...");

}

//客户要求删除一项需求

public void delete() {

System.out.println("客户要求删除一项需求...");

}

//客户要求出变更计划

public void plan() {

System.out.println("客户要求需求变更计划...");

}

}

美工组的职责是设计出一套漂亮、简单、便捷的界面

public class PageGroup extends Group {

//首先这个美工组应该被找到吧,要不你跟谁谈?

public void find() {

System.out.println("找到美工组...");

}

//美工被要求增加一个页面

public void add() {

System.out.println("客户要求增加一个页面...");

}

//客户要求对现有界面做修改

public void change() {

System.out.println("客户要求修改一个页面...");

}

//甲方是老大,要求删除一些页面

public void delete() {

System.out.println("客户要求删除一个页面...");

}

//所有的增删改那要给出计划呀

public void plan() {

System.out.println("客户要求页面变更计划...");

}

}

代码组的职责是实现业务逻辑,当然包括数据库设计了

public class CodeGroup extends Group {

//客户要求代码组过去和他们谈

public void find() {

System.out.println("找到代码组...");

}

//客户要求增加一项功能

public void add() {

System.out.println("客户要求增加一项功能...");

}

//客户要求修改一项功能

public void change() {

System.out.println("客户要求修改一项功能...");

}

//客户要求删除一项功能

public void delete() {

System.out.println("客户要求删除一项功能...");

}

//客户要求出变更计划

public void plan() {

System.out.println("客户要求代码变更计划...");

}

}

4.客户刚刚开始给了我们一份他们自己写的一份需求,还是比较完整的,需求组根据这份需求写了一份分析说明书,客户一看,不对,要增加点需求

public class Client {

public static void main(String[] args) {

//首先客户找到需求组说,过来谈需求,并修改

System.out.println("-------------客户要求增加一个需求-----------------");

Group rg = new RequirementGroup();

//找到需求组

rg.find();

//增加一个需求

rg.add();

//要求变更计划

rg.plan();

}

}

运行结果如下:

-------------客户要求增加一个需求-----------------

找到需求组...

客户要求增加一项需求...

客户要求需求变更计划...

又过了段时间,客户说“界面多画了一个,过来谈谈”

public class Client {

public static void main(String[] args) {

//首先客户找到美工组说,过来谈页面,并修改

System.out.println("-------------客户要求删除一个页面-----------------");

Group pg = new PageGroup();

//找到需求组

pg.find();

//增加一个需求

pg.delete();

//要求变更计划

pg.plan();

}

}

运行结果如下:

-------------客户要求 删除一个页面-----------------

找到美工组...

客户要求删除一个页面...

客户要求页面变更计划...

过了一天后,客户又让代码组过去,说是数据库设计问题, 然后又叫美工过去,布置了一堆命令 。

5.每次都是叫一个组去,布置个任务,然后出计划,次次都这样,如果让你当甲方也就是客户,你烦不烦?而且这种方式很容易出错误呀,客户要求找个接头人,告诉他怎么做,内部怎么处理他不管。

类图中增加了不少,看着也比较清晰,比较简单的(Command 抽象类与 Group 抽象类是没有关联关系的,与 Group 的三个实现类是有关联关系,为了线条不交叉就直接画上父类有关系。

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

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

命令的抽象类,我们把客户发出的命令定义成一个一个的对象

public abstract class Command {

//把三个组都定义好,子类可以直接使用

protected RequirementGroup rg = new RequirementGroup(); //需求组

protected PageGroup pg = new PageGroup(); //美工组

protected CodeGroup cg = new CodeGroup(); //代码组;

//只要一个方法,你要我做什么事情

public abstract void execute();

}

增加一项需求:

public class AddRequirementCommand extends Command {

//执行增加一项需求的命令

public void execute() {

//找到需求组

super.rg.find();

//增加一份需求

super.rg.add();

//给出计划

super.rg.plan();

}

}

看删除一个页面的命令,DeletePageCommand 类:

public class DeletePageCommand extends Command {

//执行删除一个页面的命令

public void execute() {

//找到页面组

super.pg.find();

//删除一个页面

super.rg.delete();

//给出计划

super.rg.plan();

}

}

再看我们的接头人,就是 Invoker 类的实现:

public class Invoker {

//什么命令

private Command command;

//客户发出命令

public void setCommand(Command command){

this.command = command;

}

//执行客户的命令

public void action(){

this.command.execute();

}

}

再看一下客户提出变更的过程:

public class Client {

public static void main(String[] args) {

//定义我们的接头人

Invoker xiaoSan = new Invoker(); //接头人就是我小三

//客户要求增加一项需求

System.out.println("-------------客户要求增加一项需求-----------------");

//客户给我们下命令来

Command command = new AddRequirementCommand();

//接头人接收到命令

xiaoSan.setCommand(command);

//接头人执行命令

xiaoSan.action();

}

}

运行结果如下:

-------------客户要求增加一项需求-----------------

找到需求组...

客户要求增加一项需求...

客户要求需求变更计划...

如果客户要求删除一个页面:

public class Client {

public static void main(String[] args) {

//定义我们的接头人

Invoker xiaoSan = new Invoker(); //接头人就是我小三

//客户要求增加一项需求

System.out.println("-------------客户要求删除一个页面-----------------");

//客户给我们下命令来

//Command command = new AddRequirementCommand();

Command command = new DeletePageCommand();

//接头人接收到命令

xiaoSan.setCommand(command);

//接头人执行命令

xiaoSan.action();

}

}

运行结果如下:

-------------客户要求删除一个页面-----------------

找到美工组...

客户要求删除一项需求...

客户要求需求变更计划...

是不是很简单,而且客户也不用知道到底要谁来修改,这个他不需要知道的,高内聚的要求体现出来了,这就是命令模式。

6.命令模式的通用类图如下:

Receiver 角色:这个就是干活的角色,命令传递到这里是应该被执行的,具体到上面我们的例子中就是Group 的三个实现类;

Command 角色:就是命令,需要我执行的所有命令都这里声明;

Invoker 角色:调用者,接收到命令,并执行命令,例子中我这里项目经理就是这个角色;

上一篇下一篇

猜你喜欢

热点阅读