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

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

   

§案例场景:

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;
        }
    }

 


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是我对一个多人在线游戏的架构设计和应用设计模式的建议: 1. 模块划分 可以将游戏功能划分成以下模块:登录、注册、角色创建、场景管理、任务系统、交易系统、聊天系统、好友系统、公告系统、排行榜系统等。 2. 设计模式应用 - 工厂方法模式:对于角色创建模块,可以使用工厂方法模式来创建不同类型的角色。 - 单例模式:对于场景管理模块,可以使用单例模式来确保只有一个场景管理器实例。 - 观察者模式:对于聊天系统、好友系统、公告系统、排行榜系统等模块,可以使用观察者模式来实现消息的发布和订阅。 - 策略模式:对于任务系统、交易系统等模块,可以使用策略模式来实现不同的任务类型和交易类型。 - 命令模式:对于一些需要撤销和重做的操作,可以使用命令模式来实现。 - 享元模式:对于场景中的重复对象,可以使用享元模式来节省内存。 3. 架构设计的实现 - 使用MVC架构:将游戏分为Model、View、Controller三层,实现模块之间的解耦。 - 使用RPC技术:使用RPC技术来实现服务器和客户端之间的通信,提高游戏性能和可维护性。 - 使用缓存技术:对于一些频繁访问的数据,可以使用缓存技术来提高游戏性能。 以上是我对一个多人在线游戏的架构设计和应用设计模式的建议。具体实现细节需要根据具体情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值