设计模式——命令模式

命令模式

定义

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

优缺点、应用场景

优点

  1. 类间解耦。调用者与接收者之间没有任何依赖关系。调用者只需要调用execute()方法即可,不需要了解哪个接收者执行。
  2. 可拓展性。
  3. 命令模式结合其他模式会更优秀。例如与责任链模式结合,实现命令族解析任务;结合模板方法模式,可以减少Command子类膨胀问题。

缺点

  1. 类的膨胀问题。如果有N个命令,则子类的数量就为N个,这可能会导致类的膨胀,需要慎重使用。

代码模拟场景

项目组有三个小组需求组、美工组、编码组,客户的每个“命令”都有可能涉及到多个组的响应,使用命令模式一方面接收客户的“命令”,另一方面根据“命令”组合出小组之间的分工。

实验小结

  1. 你永远也不知道用户到底怎么定义他的需求,每次的修改都相当于命令
  2. 如果对于每个命令都需要new来处理,那么每次都需要创建一个场景类,而且是手动的执行命令中的每个细节
  3. 命令模式要求,将一个命令中所有的细节都交给Command的实现类来做,执行命令时由唯一执行人Invoker来执行,而客户的需求只跟Invoker说明,由Invoker发布命令

命令模式

UML图

设计模式——命令模式_第1张图片

部门抽象及部门实体

/**
 * 抽象组
 */
public abstract class Group {
	// 甲乙双方分开办公,如果要和某个组讨论,首先要找到这个组
	public abstract void find();
	// 被要求增加功能
	public abstract void add();
	// 被要求删除功能
	public abstract void delete();
	// 被要求修改功能
	public abstract void change();
	// 被要求给出所有的变更计划
	public abstract void plan();
}

/**
 * 需求组
 */
public 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("客户要求删除一项需求");
	}
	@Override
	public void change() {
		System.out.println("客户要求修改一项需求");
	}
	@Override
	public void plan() {
		System.out.println("客户要求需求变更计划");
	}
}

/**
 * 美工组
 */
public class PageGroup extends Group {
	@Override
	public void find() {
		System.out.println("找到美工组。。。");
	}
	@Override
	public void add() {
		System.out.println("客户要求增加一个页面");
	}
	@Override
	public void delete() {
		System.out.println("客户要求删除一个页面");
	}
	@Override
	public void change() {
		System.out.println("客户要求修改一个页面");
	}
	@Override
	public void plan() {
		System.out.println("客户要求页面变更计划");
	}
}

/**
 * 代码组
 */
public 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("客户要求删除一项功能");
	}
	@Override
	public void change() {
		System.out.println("客户要求修改一项功能");
	}
	@Override
	public void plan() {
		System.out.println("客户要求代码变更计划");
	}
}

命令Command抽象与实现

/**
 * 抽象命令类
 */
public abstract class Command {
	// 定义好三个组,子类可以直接使用
	protected RequirementGroup requirementGroup = new RequirementGroup();
	protected PageGroup pageGroup = new PageGroup();
	protected CodeGroup codeGroup = new CodeGroup();
	// 只有一个方法:执行
	public abstract void execute();
}

/**
 * 需求组添加需求的命令
 */
public class AddRequirementCommand extends Command {
	@Override
	public void execute() {
		super.requirementGroup.find();
		super.requirementGroup.add();
		super.requirementGroup.plan();
	}
}

/**
 * 需求组添加需求的命令
 */
public class DeletePageCommand extends Command {
	@Override
	public void execute() {
		super.pageGroup.find();
		super.pageGroup.delete();
		super.pageGroup.plan();
	}
}

执行人(实施)

/**
 * 执行者
 */
public class Invoker {
	private Command command;
	// 客户发出命令
	public Invoker setCommand(Command command) {
		this.command = command;
		// 这个地方自己加的,为了方便设置命令后执行
		return this;
	}
	// 执行客户的命令
	public void action(){
		this.command.execute();
	}
}

入口类

public class CommandMain {
	public static void main(String[] args) {
//        硬核需求();
		command();
	}

	// 命令模式
	public static void command(){
		Invoker<Command> invoker = new Invoker<>();
		// 添加一个需求
		Command addRequirementCommand = new AddRequirementCommand();
		// 设置命令,在这里需要什么命令就直接new一个Command接口的实现类即可
		Command deletePageCommand = new DeletePageCommand();
		invoker.setCommand(addRequirementCommand);     // 执行
		invoker.setCommand(deletePageCommand);
		invoker.rollback(addRequirementCommand.getClass());     // 客户要求回滚
		invoker.action();
	}

	public static void 硬核需求(){
		System.out.println("-----客户要求增加一项需求-----");
		Group requirementGroup = new RequirementGroup();
		// 找到需求组
		requirementGroup.find();
		// 添加需求
		requirementGroup.add();
		// 要求变更计划
		requirementGroup.plan();
	}
}

结果

非命令模式
设计模式——命令模式_第2张图片

命令模式
设计模式——命令模式_第3张图片

参考书籍

秦小波《设计模式之禅》

你可能感兴趣的:(设计模式,设计模式,命令模式)