定义:
将请求封装成一个对象,从而让用户使用不同的请求把客户端参数化。请求排队或者记录请求日志,以及支持可撤销的操作.
要点:
1.有一个发布命令的人(Invoker请求者角色):
负责调用命令对象执行请求,通常会持有命令对象(可以持有多个命令对象)。Invoker是Client真正触发命令并要求命令执行相应操作的地方(使用命令对象的入口)。
2.具体命令(ConcreteCommand具体命令角色):
命令接口的具体实现对象,通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
3.一个抽象的执行者(Command命令角色):
定义命令的接口,声明具体命令类需要执行的方法。这是一个抽象角色。
4.具体执行者(Receiver接受者):
Receiver是真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
#######使用场景:
以《西游记》里的主人公来解说一下,唐僧发出“打妖怪”的命令,他的三个徒弟就得乖乖去做,这里唐僧就是BOSS,“打妖怪”就是命令,三个徒弟就是最终需要执行的人,至于徒弟们怎么“打怪兽”,唐老大就管不着了,这里用命令把唐老大跟三个徒弟分隔开来,以后唐老大要发布新的命令,我们只要增加命令类里的方法就可以了。
1.有一个发布命令的人(唐僧),
2.具体命令("打妖怪"),
3.一个抽象的执行者("徒弟"(下文的person类)),
4.具体执行者("悟空","八戒","沙僧"),
#######代码简单实现:
1.一个抽象的执行者(person类)
public abstract class Person {
private String name;
private String message;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
//攻击方法
public abstract String attack();
}
2.具体执行者
public class Wukong extends Person {
public Wukong() {
this.setName("悟空");
}
@Override
public String attack() {
return this.getName() + "收到'" + this.getMessage() + "'的消息并用金箍棒打妖怪";
}
}
3.具体命令
public class Command {
private Person person;
private String message;
public Command(String message) {
this.message = message;
Wukong wukong = new Wukong();
setPerson(wukong);
}
public void setPerson(Person p){
this.person = p;
}
public String execute(){
person.setMessage(message);
return person.attack();
}
}
4.有一个发布命令的人
public class Tangseng {
private Command command;
public Tangseng(Command command) {
this.command = command;
}
public String getMessage() {
return command.execute();
}
}
5.执行
public class Emperor {
public static void main(String[] args) {
Command command = new Command("打妖怪");
Tangseng tangseng=new Tangseng(command);
String result = tangseng.getMessage();
System.out.println(result);
}
}
打印结果:
悟空收到'打妖怪'的消息并用金箍棒打妖怪.
拓展
假设妖怪很厉害,唐僧要悟空去找菩萨.这时只需要重新发布一条命令就行了(只要悟空有找菩萨的方法).或者唐僧要八戒去打妖怪,这时只需要命令(具体命令(持有接受者"八戒"))八戒去就行了,到这里是不是有点明白了,这就是用命令(或叫"请求")将调用对象的操作和知道如何实现该操作的对象解耦.
以上内容总结
将调用对象的操作和知道如何实现该操作的对象解耦;
多个命令可以装配成一个复合命令
增加新的命令很容易
最后为了加深理解,看下Android中的具体应用
看到这图熟悉吧.
一个抽象的执行者
命令接口Runnable定义如下
public interface Runnable {
public abstract void run();
}
调用者Thread简化版代码:
命令模式这里不需要继承Runnable接口,但是这里考虑到实际情况,比如方便性等,继承了Runnable
接口,实现了run方法,这个是Thread自身的运行run的方法.
class Thread implements Runnable {
private Runnable target;
public Thread(Runnable target) {
this.target = target;
}
public synchronized void start() {
if (threadStatus != 0 || this != me)
throw new IllegalThreadStateException();
group.add(this);
start0();//这个是本地方法,调用run方法
if (stopBeforeStart) {
stop0(throwableFromStop);
}
}
//可选
public void run() {
if (target != null) {
target.run();
}
}
}
客户端只需要new Thread(new Runnable(){}).start()就开始执行相关的一系列的请求,这些请求大部分都是实现Runnable接口的匿名类。
该模式主要适用场景:
1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
2.系统需要在不同的时间指定请求、将请求排队和执行请求。
3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
4.系统需要将一组操作组合在一起。
好了,水平有限,讲的不是太清楚,设计模式这本武林秘籍博大精深啊,大家也多找资料理解,不对的地方清留言,一起探讨.
其他模式继续更新,敬请期待......