您的位置:首页 > 其它

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

2013-02-21 15:44 239 查看
时隔多日,最近忙于找工作和面试,一直没时间潜心看书和写博客,现在终于有时间了。

心法(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 {

//receiver
private Head head;

public ShakeCommand(Head head){
this.head=head;
}

@Override
public void execute() {
// TODO Auto-generated method stub
head.shakeHead();
}

@Override
public void run() {
// TODO Auto-generated method stub
this.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 stub
for (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!!!!
命令模式暂告段落。欢迎拍砖。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  设计模式