c#享元模式详解

这篇具有很好参考价值的文章主要介绍了c#享元模式详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基本介绍:

  享元模式的定义:运用共享技术有效地支持大量细粒度的对象重复使用。适用于大量小粒度的对象造成的运行效率和内存使用效率低下的情况。

  “享元”顾名思义,“享”共享的意思,“元”单元,最小对象,零部件的意思。

  即从字面意思不难看出,该模式旨在共享一些零部件供其使用。

  想要实现对这些零部件的重复使用,那必然需要一个类来统筹安排,负责它们的创建、使用和维护。

  如果想要实现一个零部件的使用,可以使用单例模式,所以享元模式其实也可以看做是单例模式的复数模式

  它们都是在一个固定类中对象进行创建和维护

举例说明:

  比如五子棋游戏,构成游戏的组件,无非就是无数个黑棋和白棋。

  黑棋和白棋就可以看做是两个最小的单元,在对战过程中就是在重复的创建这些单元。

  如果是一般模式一盘棋局必然要创建N多个黑棋和白棋的对象,如果是一盘游戏还可以凑合使用。

  大家想象一下,如果是个游戏平台,可以同时开展1000盘这样的棋局,那必然需要创建N*1000个黑白棋子对象。

  其实这些对象都是重复的,只有很少一部分属性(状态)不同而已,相同的是棋子本身,不同的是棋子的颜色,比如黑棋和白棋之分。

  另外该棋子在哪个棋盘、在哪个棋盘坐标就属于不可被共享的部分了,这部分内容就是非共享的。

  既然弄清楚了相同的部分和不同部分,我们就可以把相同的部分进行共享,对象个数从原来的N*1000个对象降到了2个对象

基本结构:

  通过例子也不难看出,享元模式创建的对象存在两个状态:

    内部状态:可以被共享的状态。存储在享元信息内部,并且不会随环境的改变而改变。在这里指的是棋子本身,它们不会随着棋局和选手的变化而变化。

    外部状态:不可被共享的状态。随环境的改变而改变。在这里指的是黑白棋子颜色之分。

         这里容易让人产生误区,容易把棋子所处坐标和棋盘等归在外部状态,这就大错特错了。

           能共享的都是最基本的单元,而棋子的坐标和棋盘是不断变化的,随着棋局的不同而不同,这部分是不可以被共享的,也不能被共享。

  享元模式的主要有以下角色:

    抽象享元角色(Flyweight):通常是一个接口或抽象类,声明了具体享元类公共的方法,这些方法可以为外界提供内部状态和设置外部状态。

    具体享元角色(Concrete Flyweight):实现了抽象享元类,在该类中为内部状态提供了存储空间。通常我们可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象。

    非享元角色 (Unsharable Flyweight):并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类;当需要一个非共享具体享元类的对象时可以直接通过实例化创建。本实例中,棋盘类就是非享元部分。

    享元工厂角色(Flyweight Factory):负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。

优缺点:

  优点:降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。享元模式中的外部状态相对独立,且不影响内部状态。

  缺点:为了使对象可以共享,需要将享元对象的部分状态外部化,分离内部状态和外部状态,这使得程序的逻辑更复杂,使系统复杂化。

具体实例:

  1. 抽象享元角色

     1     /// <summary>
     2     /// 享元抽象类
     3     /// </summary>
     4     public abstract class ChessPieces
     5     {
     6         public string Colour;
     7         public ChessPieces(string strColour)
     8         {
     9             Colour = strColour;
    10         }
    11 
    12       
    13         /// <summary>
    14         /// 落子规则
    15         /// </summary>
    16         /// <param name="chessBoard">棋盘信息</param>
    17         public void MoveInChess(ChessBoard chessBoard)
    18         {
    19             //这里可以将棋盘信息通过参数方式注入
    20         }
    21 
    22         //还可以设置一些 棋子的规则等等
    23     }

    享元抽象类主要是规范具体享元类供其继承,并提供其共有的属性和方法。

    本实例只是最简单的使用构造函数参数注入方式,将棋子外部状态(颜色)更新。

    而内部状态,比如棋子的具体下棋规则等等,可以在此类中声明。

    比如此实例MoveInChess方法就是通过参数注入的形式将棋盘信息注入到内容,从而落实落子的具体规则。

    规则是通用的,可以共享的,所以可以是内部状态的一部分。

  2. 具体享元角色
     1     /// <summary>
     2     /// 白棋
     3     /// </summary>
     4     public class BlackPieces : ChessPieces
     5     {
     6         public BlackPieces(string strColour) : base(strColour)
     7         {
     8 
     9         }
    10     }
    11 
    12     /// <summary>
    13     /// 黑棋
    14     /// </summary>
    15     public class WhitePieces : ChessPieces
    16     {
    17         public WhitePieces(string strColour) : base(strColour)
    18         {
    19 
    20         }
    21     }

    继承自抽象享元类,具体实现其方法。

    此实例只是通过构造函数简单的将棋子分成黑白棋子,实际中会有各种属性或方法需要在此类中实现。

  3. 享元工厂角色
        /// <summary>
        /// 棋子工厂
        /// </summary>
        public class WuziqiFactory
        {
            // 单例模式工厂
            private static WuziqiFactory wuziqiFactory;
            // 缓存存放共享对象
            private static Dictionary<string, ChessPieces> keyValuePairs = new Dictionary<string, ChessPieces>();
            // 私有化构造方法
            private WuziqiFactory()
            {
                if (keyValuePairs.Count == 0)
                {
                    keyValuePairs.Add("Black", new BlackPieces("Black"));
                    keyValuePairs.Add("White", new WhitePieces("White"));
                }
            }
    
            // 获得单例工厂
            public static WuziqiFactory GetInstance
            {
                get
                {
                    if (wuziqiFactory == null)
                    {
                        wuziqiFactory = new WuziqiFactory();
                    }
                    return wuziqiFactory;
                }
            }
    
            // 获取棋子
            public ChessPieces GetChessPieces(String type)
            {
                if (keyValuePairs.ContainsKey(type))
                {
                    return keyValuePairs[type];
                }
                return null;
            }
        }

    此实例使用单例模式创建工厂对象,保证整个项目生命周期内只存在一个棋子工厂对象,并使用GetInstance进行返回具体对象。这里可以加上锁防止并发等问题。

    另外工厂的构造函数对可共享对象进行了缓存,使用GetChessPieces获取棋子对象时,可保证其不重复创建。保证整个项目生命周期内只存在黑白两个棋子对象。

  4. 非享元角色
     1     /// <summary>
     2     /// 棋盘
     3     /// </summary>
     4     public class ChessBoard
     5     {
     6         //棋盘编号
     7         public int ChessBoardId { get; set; }
     8 
     9 
    10         //黑方棋手
    11         //白方棋手
    12         //棋盘棋子布局等等属性
    13         
    14         /// <summary>
    15         /// 初始化棋盘
    16         /// </summary>
    17         public ChessBoard()
    18         {
    19             //可以通过构造函数 初始化棋盘基础属性
    20         }
    21     }

    非享元部分,也就是不能共享的部分。

    棋盘的编号、棋盘对局双方信息和棋盘落子情况等都是每个棋盘独有的,不可共享。

    至于棋盘的落子和整体维护可以通过参数注入等形式交给棋子共享对象进行研判和操作,或者直接在棋盘类中进行声明都可以,这就看具体制定的规则了。

  5. 客户端

     1     /// <summary>
     2     /// 客户端
     3     /// </summary>
     4     class Client
     5     {
     6         static void Main(string[] args)
     7         {
     8             //创建棋盘 通过构造函数或者函数参数等形式初始化棋手、棋盘信息
     9             ChessBoard chessBoard = new ChessBoard();
    10             //获取黑方棋子1
    11             ChessPieces blackPieces1 = WuziqiFactory.GetInstance.GetChessPieces("Black");
    12             Console.WriteLine("棋子:" + blackPieces1.Colour);
    13             //获取白方棋子1
    14             ChessPieces whitePieces1 = WuziqiFactory.GetInstance.GetChessPieces("White");
    15             Console.WriteLine("棋子:" + whitePieces1.Colour);
    16 
    17             //判断两个棋子是否是同一个对象
    18             Console.WriteLine("判断两个不同颜色的棋子是否是同一个对象" + blackPieces1.Equals(whitePieces1) + "\r\n");
    19 
    20             //获取黑方棋子2
    21             ChessPieces blackPieces2 = WuziqiFactory.GetInstance.GetChessPieces("Black");
    22             Console.WriteLine("棋子:" + blackPieces2.Colour);
    23             //获取白方棋子2
    24             ChessPieces whitePieces2 = WuziqiFactory.GetInstance.GetChessPieces("White");
    25             Console.WriteLine("棋子:" + whitePieces2.Colour);
    26 
    27             //判断同一个颜色的两个棋子是否是同一个对象
    28             Console.WriteLine("判断两个不同颜色的棋子是否是同一个对象" + blackPieces1.Equals(blackPieces2) + "\r\n");
    29 
    30             Console.ReadKey();
    31         }
    32     }

    c#享元模式详解

总结:

  实现享元工厂类时使用单例模式和简单工厂模式,确保对象的唯一性,并提供方法向客户端返回享元对象。

 

 

 

 

  文章来源地址https://www.toymoban.com/news/detail-736171.html

到了这里,关于c#享元模式详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【设计模式】第十一章:享元模式详解及应用案例

    【设计模式】七大设计原则 【设计模式】第一章:单例模式 【设计模式】第二章:工厂模式 【设计模式】第三章:建造者模式 【设计模式】第四章:原型模式 【设计模式】第五章:适配器模式 【设计模式】第六章:装饰器模式 【设计模式】第七章:代理模式 【设计模式

    2024年02月13日
    浏览(29)
  • .NET高级面试指南专题二十七【享元模式介绍,通过共享对象来最大程度地减少内存使用和提高性能】

    享元模式是一种结构型设计模式,旨在通过共享对象来最大程度地减少内存使用和提高性能。 在享元模式中,对象被分为两种部分:内部状态( intrinsic state )和外部状态( extrinsic state )。内部状态是对象共享的部分,而外部状态是对象的变化部分,它们在对象被创建后可

    2024年04月27日
    浏览(28)
  • 【享元设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    享元模式(Flyweight Pattern),是一种结构型设计模式。主要用于减少创建对象的数量,以减少内存占用和提高性能。它摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,让你能在有限的内存容量中载入更多对象。 当程序需要生成数量巨大的相似

    2023年04月10日
    浏览(30)
  • 设计模式——享元模式

    享元模式(Flyweight Pattern)是池技术的重要实现方式。 使用共享对象可以有效地支持大量的细粒度对象。 优点 可以大大减少应用程序创建对象的数量,降低程序内存占用。 缺点 提高了系统的复杂度,需要分离出享元对象的外部状态(key)和内部状态(对象属性),并且外部

    2024年02月16日
    浏览(29)
  • 设计模式-享元模式

    享元模式(Flyweight Pattern)是一种结构型设计模式,主要用于减少创建大量相似对象对内存资源的消耗,通过共享这些对象来提高程序性能和系统资源利用率。在实际应用场景中string就是使用了享元模式,string a = “123”; string b = “123”; 我们假设有一个场景是需要创建大量的

    2024年01月24日
    浏览(32)
  • 设计模式:享元模式

    首先我们需要简单了解一下什么是享元模式。 享元模式(Flyweight Pattern) :主要用于减少创建对象的数量,以减少内存占用和提高性能。享元模式的重点就在这个享字,通过一些共享技术来减少对象的创建,实际上Java中String值的存储,Volley中的 ByteArrayPool 也使用到了享元模式,

    2024年02月08日
    浏览(33)
  • 构型模式-享元模式

    描述 通过共享已经存在的对象来减少对象的数量,从而提高系统的性能和效率。这种方式可以避免重复创建对象,同时也能够降低内存消耗。 适用环境 当需要创建大量细粒度的对象时使用;对象的状态可以被多个对象共享时使用。 优点: 可以大幅度减少系统中对象的数量

    2023年04月16日
    浏览(24)
  • 设计模式(22)享元模式

    一、介绍: 1、定义:享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式。 2、组成结构: (1)Flyweight(抽象享元类):通常是一个接口或

    2024年02月07日
    浏览(31)
  • 设计模式之享元模式

    本文看下一种结构型设计模式,享元模式。 当程序需要大量的重复对象,并且这些大量的重复对象只有部分属性不相同,其他都是相同的时候,就可以考虑使用享元设计模式设计模式来实现。典型的如围棋游戏中的棋子,除了颜色和位置不同外,其他都相同。射击游戏中的子

    2024年02月17日
    浏览(34)
  • 【前端设计模式】之享元模式

    享元模式是一种结构型设计模式,它通过共享对象来减少内存使用和提高性能。在前端开发中,享元模式可以用于优化大量相似对象的创建和管理,从而提高页面的加载速度和用户体验。 共享对象:享元模式通过共享相似对象来减少内存使用。相似对象可以共享一些不变的状

    2024年02月08日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包