下令模式与生活

命令模式与生活

一般的情况下,我们人与人(或者物与物)交流都是直接沟通。


下令模式与生活
 

但是,觉得这样的依赖性实现在太强的,想改变一下模式,不过,也这个也是合乎基本规律的。


下令模式与生活
 
构造了如下图:

 

 


下令模式与生活
 

好了,这个抽象的行为就是我们所要求的,而对于这个能满足我们要求的行为实现者是谁,我们不想去知道,我们能达到我们目的就得了。呵呵。
好的,引入命令模式!
定义:把一个请求或者操作封装在命令对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
结构:

Invoker类:被客户端调用,可以接受命令请求,设计命令队列,决定是否相应该请求,记录或撤销或重做命令请求,记录日志等等
Command类(一般都是Interface):将一个请求封装成一个对象,将一个请求具体化,方便对请求记录。
ConcreteCommand类,可以将Receiver对象放到这个类里面,这个类具体实现了要怎么处理这个用户的请求。
Receiver类,其实这个类可以没有,不过为了让设计看起来更整洁清楚。
如果一个系统要将系统中所有的数据更新到日志里,以便在系统崩溃时,可以根据日志里读回所有的数据更新命令,重新调用Execute()方法一条一条执行这些命令,从而恢复系统在崩溃前所做的数据更新。

很形象的例子:


下令模式与生活
 
对于这个服务员厨师的例子比较好的了。其实在生活上,例子到处都是,发生在身边的事情就很好。举个例子去说明一下。
成立一个大学生研究工作室,导师给某同学选成负责人,叫他L主任,L主任被委以重任说:“这个工作室就交给你了,发挥自己的主观能动性,一定要把这个实验室搞起来。”导师考虑得很周到,为了工作室的日常记录,安排了一个秘书,叫Z秘书。工作室分为很多个部门,有专门负责老师上课,这个专门做上课课件的,叫PPT部门,负责人A部长。有平时负责学生在线辅导测试的,叫test部门,负责人B部长,假设暂时列举这两个部门。
某日,导师有指示了,跟L主任说,现在要改革,重做PPT,另外,为了推进教育改革,增加信心,加强对学生的测试与促进学生学习的积极性。L主任接到任务后,准备下达命令让各个部门去实施!好了,这个命令下达得去用点技巧了,L主任不想像导师那样,直接命令,可能效果不是很太好,L主任想到了Z秘书。L主任把要做的事情都吩咐给Z秘书,让秘书去完成,最后还说了一句:“Z秘书呀,你要盯住他们呀,一定要让他们做完,每天都要去督促他们。”Z秘书虽然心中觉得有点不情愿,但还是答应了。
分析:
导师与L主任是直接沟通;


下令模式与生活
 

L主任下达命令:



下令模式与生活
 
 

进一步看看L主任的情况:


下令模式与生活
 
用面向对象的想法去想想,一切皆是对象,好的,那些命令也是对象,那些人也是对象。想想对于秘书还行增加一些方法,如果L主任改主意了,她不要去做这些事情了。

好啦!接下来不是逻辑来的了,用计算去模拟一下这个过程吧。用java实现。

 

Command.java
package test.Gof.command;

public interface Command {
	void excute() ;
}

PPTCommand.java
package test.Gof.command;

public class PPTCommand implements Command {
	private A a = null;

	public PPTCommand(A a) {
		this.a = a ;
	}

	
	public void excute() {
		System.out.println(a.getName()+" will go to "+"make PPT!! ");
	}

}


TestCommand.java
package test.Gof.command;

public class TestCommand implements Command {
	private B b = null;

	public TestCommand(B b) {
		this.b = b;
	}

	public void excute() {
		System.out.println(b.getName() + " will go to " + "test!! ");
	}

}

A.java
package test.Gof.command;

public class A {
	private String name = "A-department";

	public A() {
	}

	public A(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

B.java
package test.Gof.command;

public class B {
	private String name = "B-department";

	public B() {
	}

	public B(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

SecretaryZ.java
package test.Gof.command;

import java.util.ArrayList;
import java.util.List;

public class SecretaryZ {
	List<Command> record = new ArrayList<Command>();

	public SecretaryZ add(Command com){
		record.add(com) ;
		return this ;
	}
	public void notifyCom() {
		for (Command com : record) {
			com.excute();
		}
	}

	public void undo(Command command) {
		record.remove(command);
	}

	public void redo(Command command) {
		notifyCom();
	}
}

LDirector.java
package test.Gof.command;

public class LDirector {
	public static void main(String[] args) {
		A a = new A() ;
		B b = new B() ;
		Command com1 = new PPTCommand(a) ;
		Command com2 = new TestCommand(b) ;
		SecretaryZ secretary = new SecretaryZ() ;
		secretary.add(com1).add(com2).notifyCom() ;
	}
}

 

显示结果:

 

A-department will go to make PPT!!
B-department will go to test!!