• 结构型享元模式(Flyweight Pattern)


    1、意图

    享元模式:运用共享技术有效地支持大量细粒度的对象

    2、核心思想

          享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关键是区分内蕴状态和外蕴状态。

         内蕴状态存储在享元内部,不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状态不能影响内蕴状态,它们是相互独立的。

          将可以共享的状态和不可以共享的状态从常规类中区分开来,将不可以共享的状态从类里剔除出去。

          客户端不可以直接创建被共享的对象,而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量。

    3、优缺点分析

    GOOD:

    (1)运用共享技术有效地支持大量细粒度的对象(对于C++来说就是共用一个内存块啦,对象指针指向同一个地方)。

    (2)如果一个应用程序使用了大量的对象,而这些对象造成了很大的存储开销就应该考虑使用。

    (3)还有就是对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用较少的共享对象取代多组对象,此时可以考虑使用享元。

    4、实例

    我们不妨假设QQ是在服务器端将每次的对话都抽象出来形成了一个类。于是代码如下:

    class People
    {
        private string name;
        private int age;
        public string Name
        {
            get
            {
                return name;
            }
        }
        public int Age
        {
            get
            {
                return age;
            }
            set
            {
                age = value;
            }
        }
        public People(string name, int age)
        {
            this.name = name;
            this.age = age;
        }
    }

    class Chat
    {
        private People boy;
        private People girl;
        private string chatContent;
    
        public Chat(People p1, People p2)
        {
            this.boy = p1;
            this.girl = p2;
        }
        public string ChatContent
        {
            get
            {
                return chatContent;
            }
            set
            {
                chatContent = value;
            }
        }
        public People Boy
        {
            get
            {
                return boy;
            }
        }
        public People Girl
        {
            get
            {
                return girl;
            }
        }
    }

    若每次二者聊天时均将Chat实例化为一个对象,如下:

    class Program
    {
        static void Main(string[] args)
        {
            People boy=new People("PrettyBoy",20);
            People girl=new People("BeautifulGirl",18);
            Chat chat = new Chat(boy, girl);
            chat.ChatContent = "I love you";
            ChatServer.Send(chat);
        }
    }

    若如此,服务器就需要每次都去初始化一个对象,而当chatServer将此次聊天的记录发送给客户机之后,这个对象便成了垃圾对象。这样,每小时几百万的聊天次数,便有了几百万的对象垃圾。垃圾回收器GC便需要不停地去工作,回收对象。

    这就对效率产生了极大的影响。于是,我们想办法,使用享元模式来解决这个问题。

    两者聊天,他们的聊天方是不变的,因此,我们可以在服务器端去维护一个这样的Chat对象集合,如果该聊天对象已经存在,那么我们便重复去利用这个聊天对象。这样既减少了内存垃圾,又节省了创建对象的时间。

    代码如下:

    class FlyweightFactory
    {
        private IDictionary<string, Chat> cache = new Dictionary<string, Chat>();
    
        private void Add(Chat c)
        {
            cache.Add(c.Boy.Name + "_" + c.Girl.Name, c);
        }
    
        public Chat GetChat(People boy , People girl)
        {
            if (!cache.ContainsKey(boy.Name + "_" + girl.Name))
            {
                cache.Add(boy.Name + "_" + girl.Name, new Chat(boy, girl));
            }
            return cache[boy.Name + "_" + girl.Name];
        }
    }

    于是,从客户端访问该FlyweightFactory即可。

    这样,便有效控制了对象的数量。

    参考:http://www.cnblogs.com/kym/archive/2009/03/29/1424255.html

              http://www.cnblogs.com/aspnet2008/archive/2009/02/12/1387230.html

              http://www.cnblogs.com/steven_oyj/archive/2010/06/25/1765358.html

      

    刚看到以为园友对该模式的总结,挺不错的。
    1. 享元模式实际是单件模式的一个增强.
    2. 享元模式,其实类似一个容器,将需要重复全多次被创建的对像, 只创建一次并放到这个容器中, 如果有需要,则从这个容器中查找并取出.

  • 相关阅读:
    MySQL-8.0.18生成随机密码特性
    Oracle-19C新特性-自动清理网络日志文件
    Oracle-管理Data Guard Standby Database
    页面部分文字模糊问题修复
    C语言 指针数组
    C语言 指针和数组区别
    C语言 使用指针遍历数组
    阿里云服务器(ECS)在Ubuntu 18.04安装Docker
    Python总结之处理时间(time)、日期时间(datetime)、日历(calendar)
    终生制:疯狂创客圈 JAVA 架构班(又名 疯狂创客圈社群VIP)
  • 原文地址:https://www.cnblogs.com/dooom/p/1953040.html
Copyright © 2020-2023  润新知