一般的情况下,我们人与人(或者物与物)交流都是直接沟通。
但是,觉得这样的依赖性实现在太强的,想改变一下模式,不过,也这个也是合乎基本规律的。
构造了如下图:
好了,这个抽象的行为就是我们所要求的,而对于这个能满足我们要求的行为实现者是谁,我们不想去知道,我们能达到我们目的就得了。呵呵。
好的,引入命令模式!
定义:把一个请求或者操作封装在命令对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
结构:
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!!