ACTIVE OBJECT 模式(转)
作者:作者不详  发布日期:2011/04/28 22:14:32
ACTIVE OBJECT 模式(转)

ACTIVE OBJECT 模式——《敏捷软件开发 原则、模式与实践(c#版)》第21

    ACTIVE OBJECT 模式是建立在
COMMAND模式的基础上。这是实现多线程控制的一项古老的技术。该模式有多种使用方式,为许多工业系统提供了一个简单的多任务核心。

    想法很简单。考虑代码清单1-1和代码清单1-2ActiveObjectEngine 对象维护了一个 ICommand 对象的链表。用户可以向该引擎增加新的命令,或者调用 Run()Run() 函数只是遍历链表,执行并去除每个命令。 

代码清单1-1

using System;

using System.Collections.Generic;

using System.Text;

using System.Collections;

 

namespace ActiveObject

{

    public class ActiveObjectEngine

    {

        ArrayList itsCommands = new ArrayList();

 

        public void AddCommand(ICommand aCommand)

        {

            itsCommands.Add(aCommand);

        }

 

        public void Run()

        {

            while (itsCommands.Count > 0)

            {

                ICommand c = (ICommand)itsCommands[0];

                itsCommands.RemoveAt(0);

                c.Execute();

            }

        }

    }

}

代码清单1-2 

public interface ICommand

{

    void Execute();

}

    这似乎没有给人太深刻的印象。但是想象一下如果链表中的一个 ICommand 对象会克隆自己并把克隆对象放到链表的尾部,会发生什么呢?这个链表永远不会为空,Run() 函数永远不会返回。 

    考虑一下代码清单1-3中的测试用例。它创建了一个SleepCommand 对象。其中它向 SleepCommand 的构造函数中传了一个1,000ms的延迟。接着把 SleepCommand 对象放入到 ActiveObjectEngine 中。调用了 Run() 后,它将等待指定的毫秒数。

代码清单1-3

using System;

using System.Collections.Generic;

using System.Text;

using NUnit.Framework;

 

namespace ActiveObject

{

    [TestFixture]

    public class TestSleepCommand

    {

        private class WakeUpCommand : ICommand

        {

            public bool executed = false;

 

            public void Execute()

            {

                this.executed = true;

            }

        }

 

        [Test]

        public void TestSleep()

        {

            WakeUpCommand wakeup = new WakeUpCommand();

            ActiveObjectEngine e = new ActiveObjectEngine();

            SleepCommand c = new SleepCommand(1000, e, wakeup);

            e.AddCommand(c);

 

            DateTime start =DateTime.Now;

            e.Run();

            DateTime stop = DateTime.Now;

            double sleepTime = (stop - start).TotalMilliseconds;

 

            Assert.IsTrue(sleepTime >= 1000,

                string.Format("SleepTime {0} expected > 1000",sleepTime.ToString()));

            Assert.IsTrue(sleepTime <= 1100,

                string.Format("SleepTime {0} expected < 1100", sleepTime.ToString()));

            Assert.IsTrue(wakeup.executed, "Command Executed");

        }

    }

}

  我们来仔细看看这个测试用例。SleepCommand 的构造函数有 3 个参数。

        第一个:是延迟的毫秒数;

        第二个:是在其中运行该命令的ActiveObjectEngine 对象;

        第三个:是一个名为 wakeup 的另一个命令对象。

    测试的意图是 SleepCommand 会等待指定数目的毫秒,然后执行 wakeup 命令。

    代码清单1-4展示了 SleepCommand 的实现。在执行时,SleepCommand 检查自己以前是否已经执行过,如果没有,就记录下开始时间。如果没有过延迟时间,就把自己再加到 ActiveObjectEngine 中。如果过了延迟时间,就把 wakeup 命令对象加到 ActiveObjectEngine 中。 

代码清单1-4


using System;

using System.Collections.Generic;

using System.Text;

 

namespace ActiveObject

{

    public class SleepCommand : ICommand

    {

        private ICommand wakeupCommand = null;

        private ActiveObjectEngine engine = null;

        private long SleepTime = 0;

        private DateTime startTime;

        private bool started = false;

 

        public SleepCommand(long milliSeconds, ActiveObjectEngine e,

            ICommand wakeupCommand)

        {

            this.SleepTime = milliSeconds;

            this.engine = e;

            this.wakeupCommand = wakeupCommand;

        }

 

        public void Execute()

        {

            DateTime currentTime = DateTime.Now;

  



本文来源:
点击下载附件 点击下载附件 (如下载失败,请邮件通知我们寄回给您,或QQ:23404761留言.)
上一篇 下一篇