现在的位置: 首页 > 综合 > 正文

《架构模式应用 ● 设计模式》之命令者

2013年10月28日 ⁄ 综合 ⁄ 共 4308字 ⁄ 字号 评论关闭

/**************************************************************************************************
** 设计思想需要归纳与提炼,无论简单抑或复杂。当然方案未必是唯一的最佳路径,在总结
** 的过程中发现问题、改善问题;只有跳出业务,将复杂问题简单化,才能提纲挈领,寻找
** 共性与变化的制高点!
************************************************************************************************/

   

§案例场景:

1、服务系统负责接收外部调用请求,考虑性能问题,将此请求转发为异步方式执行。

     即: 通过MQ将原始请求发送至后台消息处理服务,完成业务逻辑异步Processing。

2、消息处理过程中,存在异常失败情况,需要进行二级队列Process

3、另外考虑到消息的完整性、一致性,需要通过事务来控制消息处理。

§分析设计:

       通过命令方式,将消息的发送者、接受者、调用者分别委派到场景中的各实例对象,各部分单一职责的方式来处理,另外对于并发的消息命令、特殊命令,可以指定不同的Receiver,处理不同的业务Path.

§设计实现:

1、 设计类图

 


MessageReceiver 执行消息处理操作(Receiver)

MessageCommand 消息命令(可将命令与消息分开)

IMessageInvoker 调用消息的处理方法(Invoker)

ThreadClient 创建消息并绑定消息调用者

2、 代码实现

     //ThreadClient.cs
    /// <summary>
    /// 创建消息并绑定消息调用者
    /// </summary>
    public class ThreadClient
    {
        public static List<Thread> _threadArray = new List<Thread>();

        /// <summary>
        /// 队列参数设置
        /// </summary>
        public QueueSettings QueueSettings
        {
            get;
            set;
        }

        public Thread Initialize(QueueSettings setting)
        {
            QueueSettings = setting;
            Thread thread = new Thread(new ThreadStart(this.Start));
            return thread;
        }

        /// <summary>
        /// 启动接收消息线程
        /// </summary>
        public void Start()
        {
            MessageReceiver receiver = new MessageReceiver(QueueSettings);
            Command command = new MessageCommand(receiver);
            IMessageInvoker invoker = new IMessageInvoker();

            invoker.SetCommand(command);
            invoker.ExecuteCommand();
        }
    }

IMessageInvoker.cs

    /// <summary>
    /// 调用消息的处理方法
    /// </summary>
    public class IMessageInvoker
    {
        private Command command;

        public void SetCommand(Command command)
        {
            this.command = command;
        }

        public void ExecuteCommand()
        {
            command.Execute();
        }
    }

MessageReceiver.cs

/// <summary>
    /// 执行消息处理操作
    /// </summary>
    public class MessageReceiver
    {
        /// <summary>
        /// 队列参数设置
        /// </summary>
        public QueueSettings QueueSettings
        {
            get;
            set;
        }

        private DepositOrderInfo _depositInfo = null;

        public MessageReceiver(QueueSettings setting)
        {
            QueueSettings = setting;
        }

        public int Process(object data)
        {
            #region 验证基本参数
            #endregion

            #region 填充订单明细
            #endregion

            #region 保存订单
            #endregion

            return Consts.Success;
        }
    }

MessageCommand.cs

    /// <summary>
    /// 消息命令
    /// </summary>
    public class MessageCommand : Command
    {
        MessageReceiver _receiver;
        string queuePath = string.Empty;

        public MessageCommand(MessageReceiver receiver) :
            base(receiver)
        {
            _receiver = receiver;
        }

        /// <summary>
        /// 处理消息
        /// </summary>
        public override void Execute()
        {
            QueueSettings = _receiver.QueueSettings;
            while (true)
            {
                try
                {
                    queuePath = QueueHelper.GetQueuePath(QueueSettings.QueueLevel);
                    if (!String.IsNullOrEmpty(queuePath) && SDMSMQ.GetAllMessageCount(queuePath) > 0)
                    {
                        //接收事务型消息

                        //Process
                    }

                    Thread.Sleep(QueueSettings.Interval);
                }
                catch (Exception ex)
                {
                    #region 发送到二级队列
                    #endregion

                    #region 发送到监控系统
                    #endregion
                }
            }
        }
    }

Command.cs

    /// <summary>
    /// 各类消息命令基类
    /// </summary>
    public abstract class Command
    {
        protected MessageReceiver receiver;

        protected QueueSettings QueueSettings;

        public Command(MessageReceiver receiver)
        {
            this.receiver = receiver;
        }

        public abstract void Execute();
    }

调用示例

            public static List<Thread> _threadArray = new List<Thread>();

           //一级队列线程
            Thread thread1 = new ThreadClient().Initialize(new QueueSettings { QueueLevel = QueueLevel.First, 
                Interval = Configs.GetConfig<int>("Queue1Interval") });
            thread1.Start();
            _threadArray.Add(thread1);


§总结:

    当然,通过指定不同的命令,Process不同的消息未必要通过命令者,灵活应用其他类型模式也可以完成此过程。本例主要针对命令者给出Demo。

   另外上述接受者构造器中入参QueueSettings,很多时候可作为命令中介适配器:

    public class CommandAdapterInfo
    {
        List<CommandAdapterInfo> CommandList = null;

        public CommandAdapterInfo Create()
        {
            Init();

            return this.CommandList.Find(delegate(CommandAdapterInfo _adapter)
            {
                return _adapter.CommandType == this.CommandType;
            });
        }

        void Init()
        {
            this.CommandList = new List<CommandAdapterInfo>();

            //提现
            CommandAdapterInfo adapter = new CommandAdapterInfo();
            adapter.CommandType = CommanderType.Commission;
            adapter.Receiver = new CommissionMessageReceiver(adapter);
            adapter.Command = new CommissionMessageCommand(adapter.Receiver);
            adapter.Invoker = new CommissionMessageInvoker();
            this.CommandList.Add(adapter);

            //委托付款到卡
            CommandAdapterInfo adapterPayToCard = new CommandAdapterInfo();
            adapterPayToCard.CommandType = CommanderType.PayToCard;
            adapterPayToCard.Receiver = new CommissionMessageReceiver(adapterPayToCard);
            adapterPayToCard.Command = new CommissionMessageCommand(adapterPayToCard.Receiver);
            adapterPayToCard.Invoker = new CommissionMessageInvoker();
            this.CommandList.Add(adapterPayToCard);
            
        }

        /// <summary>
        /// 命令类型
        /// </summary>
        public CommanderType CommandType
        {
            get;
            set;
        }

        /// <summary>
        /// 命令接收者
        /// </summary>
        public MessageReceiver Receiver
        {
            get;
            set;
        }

        /// <summary>
        /// 命令执行
        /// </summary>
        public Command Command
        {
            get;
            set;
        }

        /// <summary>
        /// 调用者
        /// </summary>
        public MessageInvoker Invoker
        {
            get;
            set;
        }
    }

 

 

抱歉!评论已关闭.