设计模式之享元模式

享元模式 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

(0)

相关推荐

  • 结构型模式之享元模式

    在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈.例如,围棋和五子棋中的黑白棋子,图像中的坐标点或颜色,局域网 ...

  • PHP设计模式之享元模式

    PHP设计模式之享元模式 享元模式,"享元"这两个字在中文里其实并没有什么特殊的意思,所以我们要把它拆分来看."享"就是共享,"元"就是元素 ...

  • [PHP小课堂]PHP设计模式之享元模式

    [PHP小课堂]PHP设计模式之享元模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 设计模式(11) 享元模式

    基于面向对象思想设计的应用程序有时遇到需要场景大量相同或显示对象实例的场景,这些数量庞大的实例很可能会消耗很多系统资源,最直接的就是内存了.比如要一款围棋游戏,如果每次落子都新建一个对象,将会占用大量 ...

  • 设计模式-享元模式

    定义 运用共享技术有效地支持大量细粒度的对象. 适用场景 例如,数据库连接,线程的创建开销都比较大,并且创建频率也非常高,因此就需要用到数据库连接池技术和线程池技术来共享数据库连接和线程.再例如,应用 ...

  • 无废话设计模式(9)结构型模式--享元模式

    0-前言 享元模式定义:运用共享技术有效地支持大量细粒度的对象. 1-实现 1-1.简单UML图:  1-2.代码实现 //1.抽象父类(网站父类) abstract class Website { ...

  • 设计模式 --面试高频之享元模式

    前言 享元模式是非常常用的一种结构性设计模式. 特别是在面试的时候.当我们把这一节内容掌握,我相信不管是工作中还是面试中这一块内容绝对是一大亮点. 什么是享元模式 所谓"享元",顾 ...

  • 泡图书馆,我想到了 享元模式

    回复"000"获取程序员必备电子书 大家好,我是老田,今天我给大家分享设计模式中的享元模式.用贴切的生活故事,以及真实项目场景来讲设计模式,最后用一句话来总结这个设计模式. 另外, ...

  • Flyweight享元模式

    >>返回<C#常用设计模式> 1. 简介 2. 示例 1. 简介 定义 使用共享对象可有效地支持大量的细粒度的对象. 解决问题 面向对象技术可以很好地解决一些灵活性或可扩展性问 ...