-1

我正在设计一个将创建多个Session对象的应用程序,这些对象可以以两种状态存在:“活动”和“非活动”。任何时候只有一个Session 对象可以处于“活动”状态,并且任何一个Session对象可以在其生命周期内多次在“活动”和“非活动”之间切换。对象还Session具有DurationActive类型属性TimeSpan,表示处于Session“活动”状态的总时间。

关于如何实现这一点的任何建议?

4

4 回答 4

5

要控制其他会话对象的活动/非活动状态,请查看中介者模式

http://en.wikipedia.org/wiki/Mediator_pattern

这应该允许您保持 Session 对象解耦,并将交互从您的主代码中抽象出来

于 2013-07-23T13:17:35.413 回答
4

解决方案取决于您是希望通过设置属性还是通过调用方法来实现Active 。

我将只介绍后一种选择,因为在我看来,它/代码更干净(因此,维护)。

您将需要一种MakeActive()方法(或类似方法)和一种MakeInactive()方法。

MakeActive()将要:

  1. 检查所有其他会话是否处于非活动状态(尽管这可以 - 也许应该 - 在更高级别处理)。
  2. 启动一个Stopwatch对象,该对象将是该类的私有成员。秒表何时被实例化将取决于您想要计时的确切时间:只是最后一次激活,或会话生命周期中的总激活。
  3. 使会话处于活动状态。

MakeInactive()将要:

  1. 使 seeion 处于非活动状态
  2. 停止Stopwatch对象。

然后实现TimeActive只是获取Stopwatch'Elapsed属性的一种情况,可能带有警卫,因此它仅在会话处于非活动状态时才有效。

于 2013-07-23T13:00:31.207 回答
1

感谢 Chris 对使用中介者模式的建议,我提出了我认为更好的解决方案。

为了控制访问,以下类将存在于它们自己的程序集中:

namespace Sessions
{

    public interface ISession
    {
        bool IsActive { get; }
        TimeSpan DurationActive { get; }
    }

    internal class Session : ISession
    {
        private Stopwatch _stopwatch;
        private bool _isChargeable;

        public bool IsActive
        {
            get { return _stopwatch.IsRunning; }
        }

        public TimeSpan DurationActive
        {
            get { return _stopwatch.Elapsed;  }
        }

        internal Session()
        {
            _stopwatch = new Stopwatch();
        }

        internal void Activate()   
        {
            _stopwatch.Start();
        }

        internal void Deactivate()
        {
            _stopwatch.Stop();
        }
    }

    public sealed class SessionMediator
    {

        private static readonly SessionMediator _instance = new SessionMediator();

        public static ISession CreateSession()
        {
            return _instance.createSession();
        }

        public static void ActivateSession(ISession session)
        {
            _instance.activateSession((Session)session);
        }

        private Session _currentSession = null;

        private SessionMediator() { }

        private ISession createSession()
        {
            return new Session();
        }

        private void activateSession(Session session)
        {
            // Deactivate the current session
            if (_currentSession != null)
                _currentSession.Deactivate();

            // Make the given session the current session
            _currentSession = session;

            // Activate the new current session
            if (_currentSession != null)
                _currentSession.Activate();
        }

    }

}

而我的测试程序,在一个单独的程序集中:

namespace TestSessionProgram
{
    public class Program
    {
        public void Main()
        {
            ISession session1 = SessionMediator.CreateSession();
            ISession session2 = SessionMediator.CreateSession();
            ISession session3 = SessionMediator.CreateSession();

            SessionMediator.ActiveSession(session1)
            Thread.Sleep(2000);
            Debug.Assert(session1.DurationActive == TimeSpan.FromSeconds(2));

            SessionMediator.ActiveSession(session2)
            Thread.Sleep(3000);
            Debug.Assert(session2.DurationActive == TimeSpan.FromSeconds(3));

            SessionMediator.ActiveSession(session1)
            Thread.Sleep(3000);
            Debug.Assert(session1.DurationActive == TimeSpan.FromSeconds(5));
        }
    }
于 2013-07-23T13:13:53.820 回答
0

有一个静态DateTime属性LastChange。在属性State中(或在函数中SetActive,或其他)增加了和DurationActive之间的区别。也更新到.DateTime.NowLastChangeLastChangeDateTime.Now

于 2013-07-23T13:03:43.257 回答