初学设计模式(4)-----命令模式
2013-02-21 15:44
239 查看
时隔多日,最近忙于找工作和面试,一直没时间潜心看书和写博客,现在终于有时间了。
心法(4):命令模式。
首先为了理解某个设计模式,必须得先明确,设计模式并是为了减少我们的代码书写量,也不是为了让程序更加智能化,而是为了让类和类之间的关系尽可能的低耦合,也就是,任何一个类的修改,都不会影响其他与之相关的类,对于单个类而言,则是,尽可能的高内聚,任何一个模块的修改或者添加,都不用对已有的类进行内部修改,只要做加法和减法即可。
那么命令模式,如何帮助我们做到这些呢?
在命令是模式中,有3个抽象名词,Receiver,Invoker,Command。
![](http://img.my.csdn.net/uploads/201302/21/1361431750_6598.png)
如此一来,所有的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!!!!
命令模式暂告段落。欢迎拍砖。
心法(4):命令模式。
首先为了理解某个设计模式,必须得先明确,设计模式并是为了减少我们的代码书写量,也不是为了让程序更加智能化,而是为了让类和类之间的关系尽可能的低耦合,也就是,任何一个类的修改,都不会影响其他与之相关的类,对于单个类而言,则是,尽可能的高内聚,任何一个模块的修改或者添加,都不用对已有的类进行内部修改,只要做加法和减法即可。
那么命令模式,如何帮助我们做到这些呢?
在命令是模式中,有3个抽象名词,Receiver,Invoker,Command。
![](http://img.my.csdn.net/uploads/201302/21/1361431750_6598.png)
如此一来,所有的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!!!!
命令模式暂告段落。欢迎拍砖。
相关文章推荐
- 【转】设计模式学习笔记之命令模式
- php设计模式之命令模式
- Java设计模式之八:命令模式
- 设计模式学习笔记1:UML统一建模语言初学
- 设计模式之命令模式
- Java设计模式-命令模式Command
- 设计模式之---命令模式
- iOS设计模式 - 命令
- [学习笔记]设计模式[5]-{命令模式}
- 设计模式 - 命令模式(command pattern) 撤销(undo) 详解
- 解读设计模式----命令模式(Command Pattern)
- 设计模式之命令模式(Command)
- 设计模式 - 命令模式
- 设计模式(8)——命令模式(Command Pattern,行为型)
- 从电视机的角度来看设计模式之命令模式
- 设计模式学习--命令模式(Command Pattern)
- 深入理解JavaScript系列(34):设计模式之命令模式
- 设计模式-命令模式
- 设计模式(二十二)-命令模式(Command Pattern)——命令也是类
- 设计模式(四)之命令模式