返回顶部
首页 > 资讯 > 精选 >C#设计模式如何实现
  • 946
分享到

C#设计模式如何实现

2023-06-30 17:06:00 946人浏览 独家记忆
摘要

这篇文章主要介绍“C#设计模式如何实现”,在日常操作中,相信很多人在C#设计模式如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”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#设计模式如何实现”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

    --结束END--

    本文标题: C#设计模式如何实现

    本文链接: https://lsjlt.com/news/330681.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    猜你喜欢
    • C#设计模式如何实现
      这篇文章主要介绍“C#设计模式如何实现”,在日常操作中,相信很多人在C#设计模式如何实现问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C#设计模式如何实现”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!游戏...
      99+
      2023-06-30
    • C#设计模式实现之迭代器模式
      目录前言:一、餐馆合并菜单 二、改进菜单实现 三、迭代器模式 总结前言: 迭代器模式平时用的不多,因为不管C#还是Java都已经帮我封装了,但是你是否知道平时经常在用的东西本质是怎么...
      99+
      2024-04-02
    • 如何实现单例设计模式
      这篇文章主要讲解了“如何实现单例设计模式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何实现单例设计模式”吧! 单例模式单例模式(Singleton Pattern)是 Java...
      99+
      2023-06-15
    • Java设计模式之如何实现桥接模式
      这篇文章主要为大家展示了“Java设计模式之如何实现桥接模式”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java设计模式之如何实现桥接模式”这篇文章吧。桥接模式桥接模式是将抽象部分与它的实现部...
      99+
      2023-06-15
    • Java设计模式的单例模式如何实现
      这篇文章主要介绍了Java设计模式的单例模式如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java设计模式的单例模式如何实现文章都会有所收获,下面我们一起来看看吧。单例模式单例模式顾名思义就是单一的实例...
      99+
      2023-06-29
    • java设计模式中如何实现单例模式
      这篇文章将为大家详细讲解有关java设计模式中如何实现单例模式,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。下面是一个简单的小实例://简单懒汉式 public class ...
      99+
      2023-05-30
      java
    • Java设计模式的桥接模式如何实现
      本文小编为大家详细介绍“Java设计模式的桥接模式如何实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java设计模式的桥接模式如何实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是桥接模式桥接(Bri...
      99+
      2023-07-06
    • Laravel中如何实现Repository设计模式
      本文小编为大家详细介绍“Laravel中如何实现Repository设计模式”,内容详细,步骤清晰,细节处理妥当,希望这篇“Laravel中如何实现Repository设计模式”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习...
      99+
      2023-07-04
    • Java设计模式中的策略模式如何实现
      这篇文章主要介绍了Java设计模式中的策略模式如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java设计模式中的策略模式如何实现文章都会有所收获,下面我们一起来看看吧。1 概述在平时开发中,往往会遇到这...
      99+
      2023-06-30
    • C++实现设计模式之装饰者模式详解
      目录设计模式和设计原则装饰者模式中的类案列描述代码实现总结设计模式和设计原则 装饰者模式动态地将责任附加到对象上。若要扩展功能,装饰者模式提供了比继承更有弹性的替代方案。 装饰者模式...
      99+
      2024-04-02
    • PHP如何实现职责链设计模式
      这篇文章主要介绍“PHP如何实现职责链设计模式”,在日常操作中,相信很多人在PHP如何实现职责链设计模式问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PHP如何实现职责链设计模式”的疑惑有所帮助!接下来,请跟...
      99+
      2023-07-05
    • Python中PO模式如何设计与实现
      本文小编为大家详细介绍“Python中PO模式如何设计与实现”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python中PO模式如何设计与实现”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。什么是PO模式一种在测...
      99+
      2023-07-02
    • C#设计模式实现之生成器模式和责任链模式
      目录生成器设计类图: 实现代码:优点:用途与缺点:责任链设计类图:实现代码:优点:用途和缺点:总结生成器 生成器模式:封装一个产品的构造过程,并允许按步骤构造。 现又一个...
      99+
      2024-04-02
    • C++设计模式之简单工厂模式的实现示例
      前言 在我们要使用一个对象时,就必须通过类来实例化对象,也就是需要new一个对象。在new的过程是非常复杂的,要经过读文件->解析文本->创建对象->给属性设值等过...
      99+
      2024-04-02
    • C#设计模式之适配器模式与装饰器模式的实现
      目录结构型设计模式适配器模式实现代码总结装饰器模式实现代码结构型设计模式 创建型设计模式主要是为了解决创建对象的问题,而结构型设计模式则是为了解决已有对象的使用问题。 适配器模式 适...
      99+
      2024-04-02
    • Python代码如何实现大话设计模式
      这篇文章将为大家详细讲解有关Python代码如何实现大话设计模式,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。本人接触到的面向对象语言中,只对C++和Python还算了解,为了加深对各个模式...
      99+
      2023-06-17
    • C#设计模式之工厂模式
      这是我们用得比较多的一种设计模式,也是23种标准设计模式之一,使用前面讲的简单工厂设计模式,遇到具体产品经常变换时就不太适合了,违反了开闭设计原则;怎么才能避免修改工厂类呢?工厂方法...
      99+
      2024-04-02
    • C#设计模式之策略模式
      策略模式 所谓策略其实就是做一件事情有很多很多的方法,比如说一个商场要搞促销,促销的方式有可能有很多:打折啊,满100返50啊、积分等等之类的。这种不同的促销方式在我们系统中表示就是...
      99+
      2024-04-02
    • C#设计模式之单例模式
      单例模式也是创建型模式的一种,也是23种设计模式中比较简单的一种。见名思意,在整个软件系统中,只有某个类型的一个对象,并且访问他的地方也只有一个,也就是只有一个全局对象访问点,这个实...
      99+
      2024-04-02
    • C#如何解析适配器设计模式
      这篇文章将为大家详细讲解有关C#如何解析适配器设计模式,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。今天看到一个园子里的朋友写了一篇ASP.NET的适配器设计模式的文章。其中提到了把输入的电...
      99+
      2023-06-17
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作