您的位置:首页 > 其它

设计模式之Command模式(学习笔记)

2012-02-12 16:15 417 查看
问题引入

有个一野蛮女友,她命令他男朋友帮她洗衣服。

我们用程序可以这么实现。

public class Boy {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boy(String name){
this.name = name;
}

}


public class Girl {
public void command(Boy boy){
System.out.print(boy.getName() + " 洗衣服");
}
public static void main(String[] args) {
Girl g = new Girl();
Boy b = new Boy("高尚");
g.command(b);
}
}


但是问题往往不是这么简单,这个野蛮女友越来越过分,她的需求在变化。
她要给她男朋友下各种各样的命令。如果按照刚才的实现。
我们就要不停的更改Girl的command的方法。
这不符合开闭原则。
其实,非常简单。我们只要把这个女孩的请求封装起来就行(所谓的封装变化)。

采用Command模式

public interface Command {
void execute();
}


public class ClothesCommand implements Command{

private Boy b;
public ClothesCommand(Boy b){
this.b = b;
}

@Override
public void execute() {
System.out.println(b.getName()+" 洗衣服");
}

}
class FoodCommand implements Command{

private Boy b;
public FoodCommand(Boy b){
this.b = b;
}

@Override
public void execute() {
System.out.println(b.getName()+" 买好吃的");
}

}


public class Boy {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Boy(String name){
this.name = name;
}

}


public class Girl {
private Command c;

public Command getC() {
return c;
}
public void setC(Command c) {
this.c = c;
}
public void command(){
c.execute();
}
public static void main(String[] args) {
Girl g = new Girl();
Boy b = new Boy("高尚");
g.setC(new ClothesCommand(b));
g.command();
g.setC(new FoodCommand(b));
g.command();
}
}


这样当女孩需求变化的时候,我们只需要创建一个新的实现类即可,而不用改动女孩的源码。
开闭原则的体现。

Command模式与undo

最早GOF提出Command模式的时候,Command的模式还有一个比较主要的功能。

就是实现undo(撤销)。因为,命令的执行者往往知道,命令该如何撤销。
那么Command接口就可以这么设计。

public interface Command {
void execute();
void undo();
}


可以想象一下,这样一来。实现系统的撤销工作就非常容易了。
可以用一个栈,把系统做的动作都压入栈中,当需要撤销的时候。
弹出栈中的元素,执行undo()就ok了。

一些心得

设计这个东西,仁者见仁智者见智。

学习设计模式的时候,会有很多概念,很多人有不同的理解。
由于初学,很难融合这些人的观点。索性就不要去融合。找到一个适合自己的理解。
也不要死死的去扣合概念,概念是起到辅助和表述作用的。
如果不能很好的去扣合,还不如不去扣合。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: