免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1174 | 回复: 0
打印 上一主题 下一主题

Active Object & Command Design Patterns, Java [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-10-05 09:29 |只看该作者 |倒序浏览
在**省的时候,有段时间因为推迟上线的原因,终于有了时间学习。时至今日,想起敏捷软件开发中那个经典的“单线程,多任务”的例子,何不实现他并共享呢?呵呵,无聊的假期,我想不到不做这件事情的理由。
key: command & active object design parttern java 单线程 多任务
备注:我赞同一位大师的观点:源代码是最好的文档,(请别说我懒好不好)。虽然本人水平有限,无法达到让人从代码就能将意图一目了然,所以我会尽量多写一些注释。所以请注意看注释。多谢!
Active Object 可以实现一个简单的单线程、多任务系统,之所以是单线程,是因为这些任务共享一个运行期堆栈。
1.执行引擎。引擎保存着一个命令(任务)队列,同时允许你添加新的任务;引擎负责执行这些任务。
package com;
import java.util.Iterator;
import java.util.LinkedList;
/**
* @author root
* @date 207-10-03
* @version 1.0
*/
public class Engine {
    private LinkedList list = null;
    public Engine() {
        super();
        list = new LinkedList();
    }
    public Engine(LinkedList list) {
        super();
        this.list = list;
    }
    public void run() throws Exception {
    System.out.println("Begin to run now");
  
        while (!list.isEmpty())
        {            
            Command comand = (Command)list.removeFirst();//不知道你是否会考虑为什么要将执行了的命令删除?
            comand.execute();            
        }
        
    }
    /*
     *
     * This methods add a new command, which is wait for execute, into the
     * engine's command list
     */
    protected void addCommand(Command aCommand) {
        list.add(aCommand);
    }
}
可以看出,我们实际上将要做的是向引擎中添加command.
2.command的实现。
/**
* command模式简单实现。
*/
package com;
/**
* @author root
* @version 1.0
* @since 1.0
* @date 2007-10-03
*
*/
public interface Command {
    public void execute()throws Exception;
}
ok,这是一个iterface,所有的命令都继承这个街口,这样的实现满足了可替换原则,我们可以使用Command来替换实现了该接口的任何类实例(执行execute方法)
在等待命令之前,我们来实现一个抽象基类,这个类实际上实在我写完所有代码后重构出来的,因为我发现命令中大多会引用执行引擎。
               
               
                package com;
public abstract class AbsCommand {
    Engine engine = null;
}
3.先来看看等待命令吧:
package com;
/**
* @author root
*
*/
public class WaitCommand extends AbsCommand implements Command {
    private boolean started = false;
    private long sleepTime = 0;
    private long startTime = 0;
    private Command toExcuteCommand = null;
    /**
     * @param engine
     * @param sleepTimes
     *            等待时间
     * @param wakeUpCommand
     *            等待时间到了以后执行的命令
     */
    public WaitCommand(Engine engine, long sleepTimes, Command toExcuteCommand) {
        super();
        this.engine = engine;
        this.sleepTime = sleepTimes;
        this.toExcuteCommand = toExcuteCommand;
    }
    // 当等待的时间未到达,实现对自身的clone,追加到引擎执行队列.以实现等待的目的。
    /*
     * 1.当等待的时间
    public void execute() throws Exception {
        long currentTime = System.currentTimeMillis();
        if (!this.started) {
            this.started = true;
            this.startTime = currentTime;
            engine.addCommand(this);
        } else if (currentTime - this.startTime  this.sleepTime) {
            engine.addCommand(this);
        } else {
            engine.addCommand(this.toExcuteCommand);
        }
    }
}
do you have any question?如有疑问欢迎大家来交流。我也是初学者哈。
4.接下来,我们将实现被延迟了的命令。这个命令在所有进程被唤醒之前,会不断实现向等待队列中追加等待命令,直到被唤醒
package com;
/**
* @author root
*
*/
public class DelayedCommand extends AbsCommand implements Command {
    private long controlTimes = 0;
    /**
     *
     */
    public DelayedCommand(Engine engine, long times) {
        super();
        this.engine = engine;
        this.controlTimes = times;
    }
    public void execute() throws Exception {
        
        //如果wakeUpCommand
        if (!Constants.isTimeOver) {   
        //在这里添加你要执行的任务。这个任务在唤醒之前会被不断执行   
          System.out.print(" "+this.controlTimes);  
            engine.addCommand(new WaitCommand(engine, this.controlTimes, this));
        }
        else{
        //唤醒后执行的任务
          System.out.println("ok, let's execute command to wakeup the "+this.controlTimes+"command!");
        }
    }
}
ok,不知道大家是否关注到了Constants.isTimeOver?既然如此,我们现在也要给出它的定义了:
package com;
public abstract class Constants {
    public static boolean isTimeOver = false;
}
可以看到,我们用Constants.isTimeOver来控制整个延迟,那么我们必须要一个命令来实现控制它。go on:
5.控制这个延迟的命令:
package com;
/*
* 唤醒命令(停止clone和停止追加TimeControledCommand)
* */
public class WakeUpCommand implements Command {
    public void execute() throws Exception {
        // TODO Auto-generated method stub
        Constants.isTimeOver = true;
        System.out.println("wake up command excuted!");
    }
}
6.万事具备,只欠东风:
/**
*
*/
package com;
/**
* @author root
*
*/
public class MainTest {
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Engine engine = new Engine();
        engine.addCommand(new DelayedCommand(engine, 300));
        engine.addCommand(new DelayedCommand(engine, 600));
        engine.addCommand(new DelayedCommand(engine, 900));        
        engine.addCommand(new WaitCommand(engine, 5000, new WakeUpCommand()));
        try {
            engine.run();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}
我们创建了几个DelayedCommand的实例,并且放入引擎执行队列中,每个实例都有自己的延迟。我们还创建了一个new WaitCommand(engine, 40000, new WakeUpCommand()), 它在5秒以后将全局的等待标志改变,这样我们所以的延迟任务也被唤醒。
ok, 让我们来看一下执行的结果吧:
Begin to run now
300 600 900 300 600 300 900 300 600 300 300 900 600 300 300 600 300 900 300 600 300 300 900 600 300 300 600 300 900 300 600wake up command excuted!
ok, let's execute command to wakeup the 300command!
ok, let's execute command to wakeup the 900command!
ok, let's execute command to wakeup the 600command!


本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/12811/showart_394899.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP