Java设计模式(九)---命令模式

x33g5p2x  于2021-03-13 发布在 Java  
字(4.2k)|赞(0)|评价(0)|浏览(525)

定义:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,

可以提供命令的撤销和恢复功能。

命令模式的通用模式:

该类图中

Receive接受者角色
---|该角色就是干活的角色,命令传递到这里应该是被执行的
Command命令角色
---|需要执行的所有命令都在这里声明
Invoker调用者角色
---|接收命令,并执行命令。

public class CommandTest {
	public static void main(String[] args) {
		//首先声明调用者Invoker
		MyInvoker invoker = new MyInvoker();
		//声明命令的接收者
		Receiver receiver1 = new ConcreteReceive1();
		//声明命令
		Command command1 = new ConcreteCommand1(receiver1);
		invoker.setCommand(command1);
		invoker.action();
	}
}
abstract class Receiver{
	//抽象的接收者,定义具体接受者要实现的方法
	public abstract void doSomething();
}
class ConcreteReceive1 extends Receiver{
	@Override
	public void doSomething() {
		System.out.println("接收者1号,需要执行的方法....");
	}
}
class ConcreteReceiver2 extends Receiver{
	@Override
	public void doSomething() {
		System.out.println("接收者2号,需要执行的方法...");
	}
}
abstract class Command{
	//抽象的命令类,定义要执行的命令,具体命令主体由子类来完成。
	public abstract void execute();
}
class ConcreteCommand1 extends Command{
	private Receiver receiver;
	//用构造函数来传递,具体的接收者是谁。
	public ConcreteCommand1(Receiver receiver) {
		this.receiver = receiver;
	}
	@Override
	public void execute() {
		//让接收者去执行具体的方法。
		this.receiver.doSomething();
	}
}
class ConcreteCommand2 extends Command{
	private Receiver receiver;
	//用构造函数来传递,具体的接收者是谁。
	public ConcreteCommand2(Receiver receiver) {
		this.receiver = receiver;
	}
	@Override
	public void execute() {
		//让接收者去执行具体的方法。
		this.receiver.doSomething();
	}
}
class MyInvoker{
	private Command command;
	//调用者角色,去决定具体的接收者执行什么命令
	public void setCommand(Command command) {
		this.command = command;
	}
	public void action() {
		this.command.execute();
	}
}

一个例子:

一个项目组分为需求组(require),美工组,编码组,三部分。客户在进行修改需求、美工时需要对各个部门进行交互。
但是这样的做法对客户来说十分不便捷。因此需要一个中介者替客户传达他对各项目组的需求。
他将客户一系列的命令(Command)传达给不同的项目小组。

public class CommandEx {
	public static void main(String[] args) {
		//首选创建一个指挥者实体
		Invoker invok = new Invoker();
		//命令实体要求添加一个需求
		CommandWork cw1 = new AddRequire();
		CommandWork cw2 = new DelPage();
		//指挥者,设置好命令
		invok.addCommand(cw1);
		invok.addCommand(cw2);
		//指挥者去传达命令。
		invok.action();
	}
}
abstract class GroupWork{
	/**
	 * 抽象的项目工作类,定义需要的方法供实现类去执行。
	 */
	//找具体的执行者
	public abstract void find();
	//要求添加功能
	public abstract void add();
	//要求删除功能
	public abstract void delete();
	//要求修改功能
	public abstract void change();
	//要求制定出具体的计划
	public abstract void plan();
}
/**
 * 美工组,执行任务
 * @author admin
 *
 */
class PageGroup extends GroupWork{

	@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("要求美工组制定出具体计划....");
	}
}
/*
 * 编码组,执行任务
 */
class CodeGroup extends GroupWork{

	@Override
	public void find() {
		System.out.println("找到程序员....");
	}

	@Override
	public void add() {
		System.out.println("要求程序员添加一个绚丽的功能...");
	}

	@Override
	public void delete() {
		System.out.println("要求程序员删除有bug的功能....");
	}

	@Override
	public void change() {
		System.out.println("要求程序员修改具体功能....");
	}

	@Override
	public void plan() {
		System.out.println("要求程序员制定出详细的计划....");
	}
}
/**
 * 需求组执行任务。
 * @author admin
 *
 */
class requireGroup extends GroupWork{

	@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("要求需求组制定详细的需求分析....");
	}
}
abstract class CommandWork{
	/**
	 * 模拟客户提出要求,并且让具体的项目组去执行任务。
	 */
	//这里已经知道这三类项目小组,所以在抽象类中直接实例化
	GroupWork rg = new requireGroup();
	GroupWork pg = new PageGroup();
	GroupWork cg = new CodeGroup();
	public abstract void executeWork();
}
class AddRequire extends CommandWork{
	@Override
	public void executeWork() {
		//找到需求组
		super.rg.find();
		//添加一个功能
		super.rg.add();
		//指定具体计划
		super.rg.plan();
	}
}
class DelPage extends CommandWork{
	@Override
	public void executeWork() {
		//找到需求组
		super.pg.find();
		//添加一个功能
		super.pg.delete();
		//指定具体计划
		super.rg.plan();
	}
}
class Invoker{
	/**
	 * 命令的调用者,通过该类,向项目组传达客户的命令。
	 * 相当于项目经理。
	 */
	private ArrayList<CommandWork> command_list = new ArrayList<CommandWork>();
	public void addCommand(CommandWork command){
		this.command_list.add(command);
	}
	public void action(){
		if(command_list.size()>0){
			for(CommandWork cw : command_list){
				cw.executeWork();
			}
		}
		/*//接收到命令,就去转达
		this.cw.executeWork();*/
	}
}

命令模式的优点:

  • 类间解耦
  • 可扩展性
  • 命令模式结合其他模式更优秀

相关文章