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

来源:互联网 发布:python粒子群算法 编辑:程序博客网 时间:2024/05/16 12:23
  • 问题引入
有个一野蛮女友,她命令他男朋友帮她洗衣服。

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

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;}@Overridepublic void execute() {System.out.println(b.getName()+" 洗衣服");}}class FoodCommand implements Command{private Boy b;public FoodCommand(Boy b){this.b = b;}@Overridepublic 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了。



  • 一些心得
设计这个东西,仁者见仁智者见智。
学习设计模式的时候,会有很多概念,很多人有不同的理解。
由于初学,很难融合这些人的观点。索性就不要去融合。找到一个适合自己的理解。
也不要死死的去扣合概念,概念是起到辅助和表述作用的。
如果不能很好的去扣合,还不如不去扣合。



原创粉丝点击