我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C#设计模式如何实现

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C#设计模式如何实现

这篇文章主要介绍“C#设计模式如何实现”,在日常操作中,相信很多人在C#设计模式如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#设计模式如何实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    游戏背景

    这是一个简单的打怪游戏,有玩家,有怪兽,玩家作为主角光环,有如下三个特殊能力

    • 攻击怪兽有暴击几率

    • 有几率回避怪兽攻击

    • 可以自己治疗一定生命值

    游戏实现

    角色类

    角色基类

    首先是角色类,角色类提供玩家和怪兽最基本的抽象,比如血量、攻击力、攻击和治疗。(对于怪兽来说,治疗是没有提供实现的,坏人肯定不能再治疗了)

    class Character{    public int HealthPoint { get; set; }    public int AttackPoint { get; set; }            public virtual void AttackChracter(Character opponent)    {        opponent.HealthPoint -= this.AttackPoint;        if (opponent.HealthPoint < 0)        {            opponent.HealthPoint = 0;        }    }    public virtual void Cure()    {//故意留空给子类实现    }}

    玩家类

    玩家实现了治疗功能并且有暴击几率。

    class Player : Character{    private float playerCriticalPossible;    public Player(float critical)    {        playerCriticalPossible = critical;    }    public override void AttackChracter(Character opponent)    {        base.AttackChracter(opponent);        Console.WriteLine("Player Attacked Monster");        Random r = new Random();        bool critical = r.Next(0, 100) < playerCriticalPossible * 100;        if (critical)        {            base.AttackChracter(opponent);            Console.WriteLine("Player Attacked Monster again");        }    }    public override void Cure()    {        Random r = new Random();        HealthPoint += r.Next(5, 10);        Console.WriteLine("Player cured himself");    }}

    怪兽类

    怪兽没有治疗能力但是有一定的几率丢失攻击目标。

    class Monster : Character{    private float monsterMissingPossible;    public Monster(float missing)    {        monsterMissingPossible = missing;    }    public override void AttackChracter(Character opponent)    {        Random r = new Random();        bool missing = r.Next(0, 100) < monsterMissingPossible * 100;        if (missing)        {            Console.WriteLine("Monster missed it");        }        else        {            base.AttackChracter(opponent);            Console.WriteLine("Monster Attacked player");        }    }}

    游戏类

    游戏类负责实例化玩家和怪兽、记录回合数、判断游戏是否结束,暴露可调用的公共方法给游戏操作类。

    class Game{    private Character m_player;    private Character m_monster;    private int m_round;    private float playerCriticalPossible = 0.6f;    private float monsterMissingPossible = 0.2f;    public Game()    {        m_player = new Player(playerCriticalPossible)        {            HealthPoint = 15,            AttackPoint = 2        };        m_monster = new Monster(monsterMissingPossible)        {            HealthPoint = 20,            AttackPoint = 6        };    }    public bool IsGameOver => m_monster.HealthPoint == 0 || m_player.HealthPoint == 0;    public void AttackMonster()    {                    m_player.AttackChracter(m_monster);    }    public void AttackPlayer()    {        m_monster.AttackChracter(m_player);    }    public void CurePlayer()    {        m_player.Cure();    }    public void BeginNewRound()    {        m_round++;    }    public void ShowGameState()    {        Console.WriteLine("".PadLeft(20, '-'));        Console.WriteLine("Round:{0}", m_round);        Console.WriteLine("player health:{0}", "".PadLeft(m_player.HealthPoint, '*'));        Console.WriteLine("monster health:{0}", "".PadLeft(m_monster.HealthPoint, '*'));    }}

    游戏操作类

    在我们这个简易游戏中,没有UI代码,游戏操作类负责在用户输入和游戏中搭建一个桥梁,解释用户的输入。

    class GameRunner{    private Game m_game;    public GameRunner(Game game)    {        m_game = game;    }    public void Run()    {        while (!m_game.IsGameOver)        {            m_game.BeginNewRound();            bool validSelection = false;            while (!validSelection)            {            m_game.ShowGameState();                Console.WriteLine("Make your choice: 1. attack 2. Cure");                var str = Console.ReadLine();                if (str.Length != 1)                {                    continue;                }                switch (str[0])                {                    case '1':                        {                            validSelection = true;                            m_game.AttackMonster();                            break;                        }                    case '2':                        {                            validSelection = true;                            m_game.CurePlayer();                            break;                        }                    default:                        break;                }            }            if(!m_game.IsGameOver)            {                m_game.AttackPlayer();            }        }                }}

    客户端

    客户端的代码就非常简单了,只需要实例化一个游戏操作类,然后让其运行就可以了。

    class Program{    static void Main(string[] args)    {        Game game = new Game();        GameRunner runner = new GameRunner(game);        runner.Run();    }}

    试着运行一下,

    C#设计模式如何实现

    看起来一切都好。

    加上存档

    虽然游戏可以正常运行,但是总感觉还是少了点什么。嗯,存档功能,一个游戏没有存档是不健全的,毕竟,人生虽然没有存档,但是游戏可是有的!让我们加上存档功能吧,首先想想怎么设计。

    需要存档的数据

    首先我们要明确,有哪些数据是需要存档的,在这个游戏中,玩家的生命值、攻击力、暴击率;怪兽的生命值、攻击力和丢失率,游戏的回合数,都是需要存储的对象。

    存档定义

    这是一个需要仔细思考的地方,一般来说,需要考虑以下几个地方:

    • 存档需要访问一些游戏中的私有字段,比如暴击率,需要在不破坏游戏封装的情况下实现这个功能

    • 存档自身需要实现信息隐藏,即除了游戏,其他类不应该访问存档的详细信息

    • 存档不应该和游戏存放在一起,以防不经意间游戏破坏了存档数据,应该有专门的类存放存档

    备忘录模式出场

    这个时候应该是主角出场的时候了。看看备忘录模式的定义

    在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态

    再看看UML,

    C#设计模式如何实现

    看起来完全符合我们的需求啊,Originator就是游戏类,知道如何创造存档和从存档中恢复状态,Memento类就是存档类,Caretaker是一个新类,负责保存存档。

    经过思考,我们决定采取备忘录模式,同时加入以下措施:

    • 将存档定义为游戏中的私有嵌套类,这样存档可以毫无压力的访问游戏中的私有字段,同时外界永远没有办法去实例化或者尝试通过转型来获得这个类,完美的保护了存档类

    • 存档类是一个简单的数据集合,不包含任何其他逻辑

    • 添加一个存档管理器,可以放在游戏操作类中,可以通过它看到我们当前有没有存档

    • 存档放在存档管理器中

    • 存档实现一个空接口,在存档管理器中以空接口形式出现,这样外部类在访问存档的时候,仅能看到这个空接口。而在游戏类内部,我们在使用存档之前先通过向下转型实现类型转换(是的,向下转型不怎么好,但是偶尔可以用一下)

    空接口

    interface IGameSave{}

    私有嵌套存档类

    该类存放在game里面,无压力地在不破坏封装的情况下访问game私有字段

    private class GameSave : IGameSave{    public int PlayerHealth { get; set; }    public int PlayerAttack { get; set; }    public float PlayerCritialAttackPossible { get; set; }    public int MonsterHealth { get; set; }    public int MonsterAttack { get; set; }    public float MonsterMissingPossible { get; set; }    public int GameRound { get; set; }}

    创建存档和从存档恢复

    在game中添加创建存档和从存档恢复的代码,在从存档恢复的时候,使用了向下转型,因为从存档管理器读出来的只是空接口而已

    public IGameSave CreateSave(){    var save = new GameSave()    {        PlayerHealth = m_player.HealthPoint,        PlayerAttack = m_player.AttackPoint,        PlayerCritialAttackPossible = playerCriticalPossible,        MonsterAttack = m_monster.AttackPoint,        MonsterHealth = m_monster.HealthPoint,        MonsterMissingPossible = monsterMissingPossible,        GameRound = m_round    };    Console.WriteLine("game saved");    return save;}public void RestoreFromGameSave(IGameSave gamesave){    GameSave save = gamesave as GameSave;    if(save != null)    {        m_player = new Player(save.PlayerCritialAttackPossible) { HealthPoint = save.PlayerHealth, AttackPoint = save.PlayerAttack };        m_monster = new Player(save.MonsterMissingPossible) { HealthPoint = save.MonsterHealth, AttackPoint = save.MonsterAttack };        m_round = save.GameRound;    }    Console.WriteLine("game restored");}

    存档管理器类

    添加一个类专门管理存档,此类非常简单,只有一个存档,要支持多存档可以考虑使用List

        class GameSaveStore    {        public IGameSave GameSave { get; set; }    }

    在游戏操作类添加玩家选项

    首先在游戏操作类中添加一个存档管理器

    private GameSaveStore m_gameSaveStore = new GameSaveStore();

    接着修改Run方法添加用户操作

    public void Run(){    while (!m_game.IsGameOver)    {        m_game.BeginNewRound();        bool validSelection = false;        while (!validSelection)        {            m_game.ShowGameState();            Console.WriteLine("Make your choice: 1. attack 2. Cure 3. Save 4. Load");            var str = Console.ReadLine();            if (str.Length != 1)            {                continue;            }            switch (str[0])            {                case '1':                    {                        validSelection = true;                        m_game.AttackMonster();                        break;                    }                case '2':                    {                        validSelection = true;                        m_game.CurePlayer();                        break;                    }                case '3':                    {                        validSelection = false;                        m_gameSaveStore.GameSave = m_game.CreateSave();                        break;                    }                case '4':                    {                        validSelection = false;                        if(m_gameSaveStore.GameSave == null)                        {                            Console.WriteLine("no save to load");                        }                        else                        {                            m_game.RestoreFromGameSave(m_gameSaveStore.GameSave);                        }                        break;                    }                default:                    break;            }        }        if(!m_game.IsGameOver)        {            m_game.AttackPlayer();        }    }            }

    注意,上面的3和4是新添加的存档相关的操作。试着运行一下。

    C#设计模式如何实现

    看起来一切正常,这样我们就使用备忘录模式,完成了存档读档的功能。

    到此,关于“C#设计模式如何实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    C#设计模式如何实现

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    C#设计模式如何实现

    这篇文章主要介绍“C#设计模式如何实现”,在日常操作中,相信很多人在C#设计模式如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#设计模式如何实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!游戏
    2023-06-30

    如何实现单例设计模式

    这篇文章主要讲解了“如何实现单例设计模式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现单例设计模式”吧! 单例模式单例模式(Singleton Pattern)是 Java 中最简
    2023-06-15

    java设计模式中如何实现单例模式

    这篇文章将为大家详细讲解有关java设计模式中如何实现单例模式,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。下面是一个简单的小实例://简单懒汉式 public class Singleton {
    2023-05-30

    Java设计模式的桥接模式如何实现

    本文小编为大家详细介绍“Java设计模式的桥接模式如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java设计模式的桥接模式如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是桥接模式桥接(Bri
    2023-07-06

    Java设计模式之如何实现桥接模式

    这篇文章主要为大家展示了“Java设计模式之如何实现桥接模式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java设计模式之如何实现桥接模式”这篇文章吧。桥接模式桥接模式是将抽象部分与它的实现部
    2023-06-15

    Java设计模式的单例模式如何实现

    这篇文章主要介绍了Java设计模式的单例模式如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java设计模式的单例模式如何实现文章都会有所收获,下面我们一起来看看吧。单例模式单例模式顾名思义就是单一的实例
    2023-06-29

    Laravel中如何实现Repository设计模式

    本文小编为大家详细介绍“Laravel中如何实现Repository设计模式”,内容详细,步骤清晰,细节处理妥当,希望这篇“Laravel中如何实现Repository设计模式”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习
    2023-07-04

    Java设计模式中的策略模式如何实现

    这篇文章主要介绍了Java设计模式中的策略模式如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java设计模式中的策略模式如何实现文章都会有所收获,下面我们一起来看看吧。1 概述在平时开发中,往往会遇到这
    2023-06-30

    Python中PO模式如何设计与实现

    本文小编为大家详细介绍“Python中PO模式如何设计与实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python中PO模式如何设计与实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是PO模式一种在测
    2023-07-02

    PHP如何实现职责链设计模式

    这篇文章主要介绍“PHP如何实现职责链设计模式”,在日常操作中,相信很多人在PHP如何实现职责链设计模式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PHP如何实现职责链设计模式”的疑惑有所帮助!接下来,请跟
    2023-07-05

    Python代码如何实现大话设计模式

    这篇文章将为大家详细讲解有关Python代码如何实现大话设计模式,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。本人接触到的面向对象语言中,只对C++和Python还算了解,为了加深对各个模式
    2023-06-17

    java设计模式学习之工厂方法模式如何实现

    这篇文章主要为大家展示了“java设计模式学习之工厂方法模式如何实现”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“java设计模式学习之工厂方法模式如何实现”这篇文章吧。工厂方法模式(Facto
    2023-05-31

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录