剑弑 发表于 2021-3-10 20:32:25

命令(Command)模式

   王者荣耀大家都熟悉,我们前面策略模式也讲过相关的例子;今天我们还是以王者荣耀为例,我们都知道王者荣耀每个英雄都有三个主动技能和一个普攻;哪么是不是我每次要新出一个英雄都要去改动技能释放的代码,加入新英雄的技能,代码加了还不一定正确还可能会出现Bug,这样很糟糕不是吗!!!    哪我们有什么办法去避免产生这样糟糕的情况呢?命令模式就是能帮到你!!!
    命令模式能怎样帮到我们呢?我们又该怎么去实现呢?
    我们先来看看命令模式的定义:
         "将请求封装成对象,这可以让你使用不同的请求,队列或者日志请求来参数化其他对象。"

    释放技能是不是就是我们所要做的请求,三个主动技能和普攻是不是都有释放这一步骤;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Command
{
    interface ICommands
    {
      /// <summary>
      /// 执行命令
      /// </summary>
      void Execute();
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Command
{
    class SkillOneCommand : ICommands
    {
      IHero hero;

      public SkillOneCommand(IHero hero)
      {
            this.hero = hero;
      }

      public void Execute()
      {
            hero.SkillOne();
      }
    }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Command
{
    class SkillTwoCommand : ICommands
    {
      IHero hero;
      public SkillTwoCommand(IHero hero)
      {
            this.hero = hero;
      }

      public void Execute()
      {
            hero.SkillTwo();
      }
    }
}

其他两个自行补上.
技能有了,我们要怎么释放呢?又怎么实现精准的释放技能呢?这时我们是不是该有一个技能的管理类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Command
{
    /// <summary>
    /// 命令控制器
    /// </summary>
    class CommandControl
    {
      Dictionary<string, ICommands> dicCommand;

      public CommandControl()
      {
            dicCommand = new Dictionary<string, ICommands>();
      }

      /// <summary>
      /// 设置命令
      /// </summary>
      /// <param name="sCommand"></param>
      public void SetCommand(string sNameCommand,ICommands sCommand)
      {
            dicCommand.Add(sNameCommand, sCommand);
      }

      /// <summary>
      /// 执行命令
      /// </summary>
      /// <param name="commandName"></param>
      public void ExecuteCommand(string commandName)
      {
            dicCommand.Where(p => p.Key == commandName).FirstOrDefault().Value.Execute();
      }

    }
}

细心的朋友会问,技能类构造函数的IHero是什么?
其实它只是个接收者类,我们发出释放技能的请求总得要个接收请求的英雄吧!IHero承担的就是这么一个角色,接收者类可以是任何类。
最后附上类图:

         (没下载UML画图工具,可以自行网上查一张)
测试代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Command
{
    class Program
    {
      static void Main(string[] args)
      {
            CommandControl control = new CommandControl();
            control.SetCommand(typeof(SkillOneCommand).FullName, new SkillOneCommand(new LiChan()));
            control.SetCommand(typeof(GeneralAttackCommand).FullName, new GeneralAttackCommand(new LiChan()));
            control.SetCommand(typeof(SkillTwoCommand).FullName, new SkillTwoCommand(new LiChan()));
            control.SetCommand(typeof(SkillThreeCommand).FullName, new SkillThreeCommand(new LiChan()));
            Console.WriteLine($"我是 {typeof(LiChan).Name},我将");
            control.ExecuteCommand(typeof(SkillOneCommand).FullName);
            control.ExecuteCommand(typeof(GeneralAttackCommand).FullName);
            control.ExecuteCommand(typeof(SkillTwoCommand).FullName);
            control.ExecuteCommand(typeof(SkillThreeCommand).FullName);
            Console.Read();
      }
    }
}

结果




剑弑 发表于 2021-3-10 20:35:23

看来我还是适合直接上传源码:Q

ibcadmin 发表于 2021-3-13 18:34:14

可以可以简单易懂

剑弑 发表于 2021-3-16 08:09:01

ibcadmin 发表于 2021-3-13 18:34
可以可以简单易懂

{:2_40:}

ibcadmin 发表于 2021-9-29 19:00:32

123
页: [1]
查看完整版本: 命令(Command)模式