初学设计模式(4)-----命令模式

来源:互联网 发布:热力学 统计物理 知乎 编辑:程序博客网 时间:2024/05/10 19:48

时隔多日,最近忙于找工作和面试,一直没时间潜心看书和写博客,现在终于有时间了。

心法(4):命令模式。

首先为了理解某个设计模式,必须得先明确,设计模式并是为了减少我们的代码书写量,也不是为了让程序更加智能化,而是为了让类和类之间的关系尽可能的低耦合,也就是,任何一个类的修改,都不会影响其他与之相关的类,对于单个类而言,则是,尽可能的高内聚,任何一个模块的修改或者添加,都不用对已有的类进行内部修改,只要做加法和减法即可。

那么命令模式,如何帮助我们做到这些呢?

在命令是模式中,有3个抽象名词,Receiver,Invoker,Command。


如此一来,所有的Command,Receiver便通过一个Invoker给隔离开,并且Invoker也无需知道Command是哪种类型,只需hold住一个接口引用即可。

上代码,这样看得更清楚一些。

Receiver:

public class Head {private static Head head;private static int times;private Head(){}public static Head getInstance(){if(head==null){synchronized (Head.class) {if(head==null){head=new Head();times=0;}}}return head;}public void prepareHead(){System.out.println("My head got prepared...");}public void shakeHead(){System.out.println("My head is shaking for "+(++times)+"...Oh my godddd!!!!");}public void dropHead(){System.out.println("Ohhhhh....I drop my head...I got headless....");}}
Invoker:

public class BrainInvoker {private Command cmd;public void setCommand(Command cmd){this.cmd=cmd;}public void doWhatchaDo(){cmd.execute();}}

Command接口:

public interface Command extends Runnable {public void execute();}

实际Command类:

public class ShakeCommand implements Command {//receiverprivate Head head;public ShakeCommand(Head head){this.head=head;}@Overridepublic void execute() {// TODO Auto-generated method stubhead.shakeHead();}@Overridepublic void run() {// TODO Auto-generated method stubthis.execute();}}
如上述代码可看出,Invoker只是hold住一个Command的接口引用,而无需知道是哪种command,如此,那任何实现了Command接口的类都可以被Invoker或许被执行。而每个Command hold与之对应的Receiver引用,在execute()中由之调用对应的action。这样,command就如同一条脑部指令,经过脑部的传输让对应部位晃动,而脑部无需知道是哪条Command,Command和Receiver已经有了对应的关系。

后面附上在多线程环境中,通过一个command队列,同步执行所有的command。

JobQueue:

public class JobQueue {@SuppressWarnings("rawtypes")private static List jobsQueue=Collections.synchronizedList(new LinkedList<Command>());private JobQueue(){}@SuppressWarnings("rawtypes")public static List getjobsQueue(){return jobsQueue;}}
Main:

public class Main {/** * @param args */@SuppressWarnings("unchecked")public static void main(String[] args) {// TODO Auto-generated method stubfor (int i = 0; i < 10; i++) {Head h = Head.getInstance();ShakeCommand cmd = new ShakeCommand(h);JobQueue.getjobsQueue().add(cmd);}while(JobQueue.getjobsQueue().size()>0){Command m=(Command)JobQueue.getjobsQueue().get(0);JobQueue.getjobsQueue().remove(0);Thread th=new Thread(m);th.start();}}}

以上即可模拟一个web server,任何一条request都可以被看成一个command然后进入队列,然后再从队列中取出每条Command,包装成一个线程,让其执行,直到队列为空。

执行结果:

My head is shaking for 1 times...Oh my godddd!!!!My head is shaking for 5 times...Oh my godddd!!!!My head is shaking for 4 times...Oh my godddd!!!!My head is shaking for 2 times...Oh my godddd!!!!My head is shaking for 3 times...Oh my godddd!!!!My head is shaking for 6 times...Oh my godddd!!!!My head is shaking for 7 times...Oh my godddd!!!!My head is shaking for 8 times...Oh my godddd!!!!My head is shaking for 9 times...Oh my godddd!!!!My head is shaking for 10 times...Oh my godddd!!!!

命令模式暂告段落。欢迎拍砖。

原创粉丝点击