Click here to Skip to main content
15,896,063 members
Articles / Desktop Programming / Win32

Evolving Responsible, Self-Describing Components

Rate me:
Please Sign up or sign in to vote.
4.81/5 (9 votes)
25 Apr 2008CPOL21 min read 23.1K   64   29  
How self-describing components can emerge from responsibility-driven development practices, and how use of the Visual Studio 'code regions' tool can add value to this process.
/*
 * Copyright 2008 Oculo Consulting Limited
 * 
*/
using System;
using System.Collections.Generic;

namespace ResponsibilitiesExample
{
    public class BufferedChannelQueue : IMessageQueue
    {
        #region Private Fields

        private Queue<IMessage> _messageQueue;
        private int _queueCapacity;
        private IMessageChannel _messageChannel;

        #endregion

        #region Constructors

        public BufferedChannelQueue(IMessageChannel messageChannel, int queueCapacity)
        {
            _messageChannel = messageChannel;
            _queueCapacity = queueCapacity;
            _messageQueue = new Queue<IMessage>(_queueCapacity);
        }

        #endregion

        #region IMessageQueue Members

        public event EventHandler<MessageForwardedEventArgs> MessageForwarded;

        public void Purge()
        {
            ForwardMessages();
        }

        public int MessageCount
        {
            get
            {
                return _messageQueue.Count;
            }
        }

        #endregion

        #region IMessageHandler Members

        public void PutMessage(IMessage message)
        {
            _messageQueue.Enqueue(message);

            if (_messageQueue.Count >= _queueCapacity)
            {
                // Queue is at capacity, so forward all messages.
                ForwardMessages();
            }
        }

        #endregion

        #region Protected Methods

        protected void NotifyMessageForwarded(IMessage message)
        {
            if (MessageForwarded != null)
            {
                MessageForwarded(this, new MessageForwardedEventArgs(message));
            }
        }

        #endregion

        #region Private Methods

        private void ForwardMessages()
        {
            IMessage messageToForward;

            while (_messageQueue.Count > 0)
            {
                messageToForward = _messageQueue.Dequeue();

                _messageChannel.PutMessage(messageToForward);

                NotifyMessageForwarded(messageToForward);
            }
        }

        #endregion
    }

    namespace ResponsibilityFocused
    {
        /// <summary>
        /// This version of BufferedChannelQueue provides an identical implementation, but describes itself in terms of responsibility.
        /// </summary>
        public class BufferedChannelQueue : IMessageQueue
        {
            #region Responsibilities

            #region Provide Instance Configured for Specific Destination Channel and Queue Capacity

            /// <summary>
            /// The destination channel is dependency-injected.
            /// </summary>
            /// <param name="messageChannel"></param>
            /// <param name="queueCapacity"></param>
            public BufferedChannelQueue(IMessageChannel messageChannel, int queueCapacity)
            {
                _messageChannel = messageChannel;
                _queueCapacity = queueCapacity;
                _messageQueue = new Queue<IMessage>(_queueCapacity);
            }

            #endregion

            #region Manage Buffer Capacity

            private int _queueCapacity;

            #endregion

            #region Know Destination Channel

            private IMessageChannel _messageChannel;

            #endregion

            #region Accept and Store Message

            #region Store Messages in a Collection with "First-in, First-out" Order

            private Queue<IMessage> _messageQueue;

            #endregion

            public void PutMessage(IMessage message)
            {
                QueueMessage(message);

                if (_messageQueue.Count >= _queueCapacity)
                {
                    // Queue is at capacity, so forward all messages.
                    ForwardMessages();
                }
            }

            #endregion

            #region Queue a Message

            private void QueueMessage(IMessage message)
            {
                _messageQueue.Enqueue(message);
            }

            #endregion

            #region Know Number of Pending Messages (Message Count)

            public int MessageCount
            {
                get { return _messageQueue.Count; }
            }

            #endregion

            #region Forward All Messages to Destination Channel

            private void ForwardMessages()
            {
                IMessage messageToForward;

                while (_messageQueue.Count > 0)
                {
                    messageToForward = _messageQueue.Dequeue();

                    _messageChannel.PutMessage(messageToForward);

                    NotifyMessageForwarded(messageToForward);
                }
            }

            #endregion

            #region Purge Queued Messages (Forward All Messages)

            public void Purge()
            {
                ForwardMessages();
            }

            #endregion

            #region Notify Message Originator When Message Forwarded

            public event EventHandler<MessageForwardedEventArgs> MessageForwarded;

            protected void NotifyMessageForwarded(IMessage message)
            {
                if (MessageForwarded != null)
                {
                    MessageForwarded(this, new MessageForwardedEventArgs(message));
                }
            }

            #endregion

            #endregion
        }

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Oculo Consulting Limited
United Kingdom United Kingdom
Matthew Cannon is a software developer and architect who has for the last 10 years focused on object-oriented design. His areas of interest are OOD, patterns, Agile practices, C# and all things .Net.

Comments and Discussions