1. 命令模式的引入
1.1 有三个组分别为需求组、美工组、代码组,客户对开发的产品有些地方需要修改,修改对应的功能就要找到对应的组别。如下UML:
具体代码实现:
abstract class Group{
//甲乙双方式分开办公,所以甲方需要通过find方法来找到对应的组
public abstract void find();
//增加一个功能
public abstract void add();
public abstract void delete();
}
class RequirementGroup extends Group{
@Override
public void find() {
System.out.println("找到需求组。。。");
}
@Override
public void add() {
System.out.println("客户要求增加一项需求。。。");
}
@Override
public void delete() {
System.out.println("客户要求删除一项需求。。。");
}
}
class CodeGroup extends Group{
@Override
public void find() {
System.out.println("客户找到代码组。。。");
}
@Override
public void add() {
System.out.println("客户要求增加一项功能。。。");
}
@Override
public void delete() {
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 class Client {
public static void main(String[] args) {
Group group = new RequirementGroup();
group.find();
group.add();
group = new PageGroup();
group.find();
group.add();
group = new CodeGroup();
group.find();
group.add();
}
}
这样问题出现了,客户需要了解每个组的职能,然后根据自己需求找到具体的组别,而不是关注自己的命令是否被执行了。
1.2 我们对上述实现方式进行优化,增加一个Invoker
来屏蔽客户对组别的依赖。
具体代码实现:
abstract class Group{
//甲乙双方式分开办公,所以甲方需要通过find方法来找到对应的组
public abstract void find();
//增加一个功能
public abstract void add();
public abstract void delete();
}
class RequirementGroup extends Group{
@Override
public void find() {
System.out.println("找到需求组。。。");
}
@Override
public void add() {
System.out.println("客户要求增加一项需求。。。");
}
@Override
public void delete() {
System.out.println("客户要求删除一项需求。。。");
}
}
class CodeGroup extends Group{
@Override
public void find() {
System.out.println("客户找到代码组。。。");
}
@Override
public void add() {
System.out.println("客户要求增加一项功能。。。");
}
@Override
public void delete() {
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("客户要求删除一个页面...");
}
}
class Invoker{
private String command;
public Invoker(String command) {
super();
this.command = command;
}
public void execute(){
if("addRequirement".equals(command)){
Group group = new RequirementGroup();
group.find();
group.add();
}else if("addPage".equals(command)){
Group group = new PageGroup();
group.find();
group.add();
}
}
}
public class Client {
public static void main(String[] args) {
Invoker invoker = new Invoker("addRequirement");
invoker.execute();
}
}
这样优化后还是存在问题,一是字符串是没有约束力的,二是对于扩展不方便。为了把命令的接受者(Group)和命令发起者分离。使命令的发起者和命令(Command)关联,这样命令发起者只需要知道有什么命令就可以了。
这样我们就引入了命令模式
2. 命令模式
- 组别
Group
在Command
抽象类中创建,初始化Invoker
时需要传入Command
- 具体代码实现:
abstract class Group{
//甲乙双方式分开办公,所以甲方需要通过find方法来找到对应的组
public abstract void find();
//增加一个功能
public abstract void add();
public abstract void delete();
}
class RequirementGroup extends Group{
@Override
public void find() {
System.out.println("找到需求组。。。");
}
@Override
public void add() {
System.out.println("客户要求增加一项需求。。。");
}
@Override
public void delete() {
System.out.println("客户要求删除一项需求。。。");
}
}
class CodeGroup extends Group{
@Override
public void find() {
System.out.println("客户找到代码组。。。");
}
@Override
public void add() {
System.out.println("客户要求增加一项功能。。。");
}
@Override
public void delete() {
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("客户要求删除一个页面...");
}
}
abstract class Command{
protected Group codeGroup = new CodeGroup();
protected Group pageGroup = new PageGroup();
protected Group requirementGroup = new RequirementGroup();
public abstract void execute();
}
class AddFunctionCommand extends Command{
@Override
public void execute() {
super.codeGroup.find();
super.codeGroup.add();
}
}
class AddPageCommand extends Command{
@Override
public void execute() {
super.pageGroup.find();
super.pageGroup.add();
}
}
class AddRequirementCommand extends Command{
@Override
public void execute() {
super.requirementGroup.find();
super.requirementGroup.add();
}
}
class Invoker{
private Command command;
public Invoker(Command command) {
super();
this.command = command;
}
public void execute(){
command.execute();
}
}
public class Client {
public static void main(String[] args) {
Invoker invoker = new Invoker(new AddRequirementCommand());
invoker.execute();
invoker = new Invoker(new AddPageCommand());
invoker.execute();
invoker = new Invoker(new AddFunctionCommand());
invoker.execute();
}
}
运行结果:
找到需求组。。。
客户要求增加一项需求。。。
客户找到美工组…
客户要求新增一个页面…
客户找到代码组。。。
客户要求增加一项功能。。。
小结
命令模式的优点:
- 实现类之间的解耦(之前客户直接与各组相关联,优化后客户只与命令相关联)
- 具有可扩展型,扩展一个命令特别简单
缺点:
- 命令泛滥,N种组合命令