请选择 进入手机版 | 继续访问电脑版

马上加入IBC程序猿 各种源码随意下,各种教程随便看! 注册 每日签到 加入编程讨论群

C#教程 ASP.NET教程 C#视频教程程序源码享受不尽 C#问题入口 ASP.NET问题入口

【C#问题提交】 社群合作 申请版主 程序开发 【远程协助】 每天乐一乐 每日签到 【承接毕业设计】 面试-葵花宝典下载

官方一群:

官方二群:

查看: 664|回复: 3

命令(Command)模式

[复制链接]
  • TA的每日心情
    开心
    2019-8-30 08:53
  • 签到天数: 198 天

    [LV.7]常住居民III

    48

    主题

    213

    帖子

    5802

    积分

    论坛元老

    Rank: 8Rank: 8

    积分
    5802
    QQ
    发表于 2021-3-10 20:32:25 | 显示全部楼层 |阅读模式

    马上加入IBC,查看更多教程

    您需要 登录 才可以下载或查看,没有帐号?立即注册

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

        释放技能是不是就是我们所要做的请求,三个主动技能和普攻是不是都有释放这一步骤;
    [C#] 纯文本查看 复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Command
    {
        interface ICommands
        {
            /// <summary>
            /// 执行命令
            /// </summary>
            void Execute();
        }
    }
    

    [C#] 纯文本查看 复制代码
    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();
            }
        }
    }
    

    [C#] 纯文本查看 复制代码
    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();
            }
        }
    }
    

    其他两个自行补上.
    技能有了,我们要怎么释放呢?又怎么实现精准的释放技能呢?这时我们是不是该有一个技能的管理类:
    [C#] 纯文本查看 复制代码
    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承担的就是这么一个角色,接收者类可以是任何类。
    最后附上类图:
    11111.png
             (没下载UML画图工具,可以自行网上查一张)
    测试代码
    [C#] 纯文本查看 复制代码
    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();
            }
        }
    }
    

    结果
    222222.png



    Command.rar

    40.45 KB, 阅读权限: 20, 下载次数: 0

  • TA的每日心情
    开心
    2019-8-30 08:53
  • 签到天数: 198 天

    [LV.7]常住居民III

    48

    主题

    213

    帖子

    5802

    积分

    论坛元老

    Rank: 8Rank: 8

    积分
    5802
    QQ
     楼主| 发表于 2021-3-10 20:35:23 | 显示全部楼层
    看来我还是适合直接上传源码
  • TA的每日心情
    开心
    前天 17:07
  • 签到天数: 1794 天

    [LV.Master]伴坛终老

    4252

    主题

    6208

    帖子

    12万

    积分

    管理员

    IBC编程社区-原道楠

    Rank: 9Rank: 9Rank: 9

    积分
    122641

    推广达人突出贡献优秀版主荣誉管理论坛元老

    发表于 2021-3-13 18:34:14 | 显示全部楼层
    可以可以  简单易懂
    C#论坛 www.ibcibc.com IBC编程社区
    C#
    C#论坛
    IBC编程社区
  • TA的每日心情
    开心
    2019-8-30 08:53
  • 签到天数: 198 天

    [LV.7]常住居民III

    48

    主题

    213

    帖子

    5802

    积分

    论坛元老

    Rank: 8Rank: 8

    积分
    5802
    QQ
     楼主| 发表于 2021-3-16 08:09:01 | 显示全部楼层
    ibcadmin 发表于 2021-3-13 18:34
    可以可以  简单易懂

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则