• 设计模式之享元模式


    享元模式 Flyweight

    Intro

    享元是指一个可复用的对象,通过复用这个享元来减少应用中的内存分配。

    享元模式是为了减少内存占用,尽可能复用已有对象的设计模式,一般来说会把这个可复用的对象放到一个外部的数据结构中,当需要使用到的时候传给享元。

    享元模式的意图是复用对象,节省内存,前提是享元对象是不可变对象。

    具体来讲,当一个系统中存在大量重复对象的时候,我们就可以利用享元模式,将对象设计成享元,在内存中只保留一份实例,供多处代码引用,这样可以减少内存中对象的数量,以起到节省内存的目的。

    实际上,不仅仅相同对象可以设计成享元,对于相似对象,我们也可以将这些对象中相同的部分(字段),提取出来设计成享元,让这些大量相似对象引用这些享元。

    Sample

    public abstract class Flyweight
    {
        public abstract void Operation(int extrinsicstate);
    }
    
    public class ConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("operation in ConcreteFlyweight");
        }
    }
    
    public class UnsharedFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("operation in UnsharedFlyweight");
        }
    }
    
    public class FlyWeightFactory
    {
        private readonly ConcurrentDictionary<string, Flyweight> _flyweights = new ConcurrentDictionary<string, Flyweight>();
    
        public Flyweight GetFlyweight(string name) => _flyweights.GetOrAdd(name, n => new ConcreteFlyweight());
    }
    
    public class Program
    {
        public static void Main(string[] args)
        {
            var counter = 20;
    
            var factory = new FlyWeightFactory();
            factory.GetFlyweight("X").Operation(counter--);
            factory.GetFlyweight("Y").Operation(counter--);
            factory.GetFlyweight("X").Operation(counter--);
    
            new UnsharedFlyweight().Operation(counter--);
    
            factory.GetFlyweight("X").Operation(counter--);
    
            Console.WriteLine(counter);
            Console.ReadLine();
        }
    }
    

    More

    享元模式的代码实现非常简单,主要是通过工厂模式,在工厂类中,通过一个 Dictionary 或数组等 来缓存已经创建好的享元对象,以达到复用的目的,可以参考上面的示例。

    来看一道经典的 C# 面试题目:

    var a = "Hello World";
    var b = "Hello World";
    Console.WriteLine(ReferenceEquals(a, b));
    

    想一下输出结果是什么,不确定的话可以试一下哈

    CLR 中 string 是一个特殊的类型,string 有一个字符串池(Intern) 的实现就属于是享元模式的体现,这也是上面的输出结果的原因,相同的字符串变量值指向了同一块内存地址

    Reference

  • 相关阅读:
    javascript对象Math和正则对象
    javascript的Date对象
    初识Python与条件判断
    数据降维_矩阵分析笔记
    数据可视化实战:如何给陈奕迅的歌曲做词云展示?
    数据采集实战:如何自动化运营微博?
    MySQL与Python交互
    27_MySQL数字函数(重点)
    26_ mysql数据操作语言:DELETE语句
    25_MySQL 数据操作语言:UPDATE语句
  • 原文地址:https://www.cnblogs.com/weihanli/p/flyweight-pattern.html
Copyright © 2020-2023  润新知