一、定义
命令模式: 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或者
记录请求日志,以及支持可撤销的操作。
二、自己的理解
这种定义性质的文字每次要看很久,自己的理解就是 :命令模式就 是 下达命令(上面的请求) 和真正的执行分开, 去饭店吃饭,我负责点菜,点了鱼,肉,蔬菜,我不关心是哪个厨师做的,只要能上菜吃到就行,如我要一个系统,只要给我一个系统就行,我不关心哪种语言实现,此外还可以随时撤销.
三、类图
四、例子
4.1 还是以点菜为例子:创建COmmand 类:
public interface Command {
void excute();
}
4.2 具体命令执行者(鱼,肉,蔬菜三种菜):
public class FishCommand implements Command {
private Receiver receiver;
public FishCommand(FishReceiver receiver) {
this.receiver = receiver;
}
@Override
public void excute() {
receiver.action();
}
}
public class MeatCommand implements Command {
private Receiver receiver;
public MeatCommand(MeatReceiver receiver) {
this.receiver = receiver;
}
@Override
public void excute() {
receiver.action();
}
}
public class VegetablesCommand implements Command{
private Receiver receiver;
public VegetablesCommand(VegetablesReceiver receiver) {
this.receiver = receiver;
}
@Override
public void excute() {
receiver.action();
}
}
4.3 接下来创建一个接受者类(分别是 鱼,肉,蔬菜对应的厨师):
public interface Receiver {
void action();
}
4.4 各个厨师的实现:
public class MeatReceiver implements Receiver {
@Override
public void action() {
System.out.println("meat ...");
}
}
public class FishReceiver implements Receiver {
@Override
public void action() {
System.out.println(" Fish ...");
}
}
public class VegetablesReceiver implements Receiver {
@Override
public void action() {
System.out.println(" vegetables ...");
}
}
4.5 创建invoker,这个主要是收集命令:
public class Invoker {
private List<Command> commandList = new ArrayList<>();
public void addCommand(Command com){
this.commandList.add(com);
}
public void display(){
for(Command com : commandList){
com.excute();
}
}
}
4.6 创建Client端:
public class Client {
public static void main(String[] args) {
// 叫来服务员
Invoker waiter = new Invoker();
//点菜
waiter.addCommand(new FishCommand(new FishReceiver()));
waiter.addCommand(new MeatCommand(new MeatReceiver()));
waiter.addCommand(new VegetablesCommand(new VegetablesReceiver()));
//确定,让厨师开始做
waiter.display();
}
}
我觉得 这里调用 new FishCommand(new FishReceiver()) ,不应该把接受者暴露出来,发命令者根本不需要关系具体的执行者,所以这里 可以将 具体命令和具体的执行者关联,不需要在发布命令的时候定义。—可能不对,自己的理解
五、小结
命令模式很好的将两个过程解藕,把发布命令和 执行者 分开了,扩张性也比较好,在Java 中很多地方用到,如Runable 就是一个典型的例子,缺点就是很多设计模式都有的,Command 子类越来越多的膨胀问题,整体理解起来还是比较简单。