Flyweight 享元模式简介与 C# 示例【结构型6】【设计模式来了_11】
〇、简介
1、什么是享元模式?
一句话解释:
将相似或同类的对象共享同一个对象,将这些对象暂存在列表中,使用时直接取出,避免每次使用时都要新建浪费资源。
享元模式的目的是减少对象的创建,通过共享对象来提高系统的性能。享元设计模式将对象的实例分为两种:内部共享对象和外部共享对象。内部共享对象是由享元类创建的,可以被多个对象共享。外部共享对象是由客户端创建的,不能被多个对象共享。
官方意图描述:运用共享技术有效地支持大量细粒度的对象。
一个比喻:(学校的足球场和篮球馆)
首先对于学校的足球场和篮球馆有共享属性,当有足球比赛时,就对应的是足球场,有篮球比赛时,对应的就是篮球馆,不会每次比赛都去新建场馆。
2、享元模式的优缺点和适用场景
优点:
- 减少对象的创建:享元设计模式通过共享对象来减少对象的创建,这样可以减少内存占用从而提高系统的性能。
 - 简化客户端代码:客户端只需要与享元接口交互,而不需要了解底层的具体实现细节,从而简化了客户端的代码。
 - 提高系统的扩展性:享元设计模式通过共享对象来提高系统的扩展性,这样可以方便地添加新的共享对象。
 - 降低系统的耦合度:享元模式将对象的创建和使用分离开来,使得系统的各个部分之间的耦合度降低,提高了系统的可维护性和可扩展性。
 
缺点:
- 增加了系统的复杂性:享元模式需要引入额外的享元工厂类和享元类,增加了系统的复杂性。
 - 可能增加系统的维护成本:享元模式可能会增加系统的维护成本,因为需要考虑如何更新对象、如何维护对象、如何测试对象等问题。
 - 影响系统的稳定性:当新增类型时,需要对享元工厂进行修改,可能导致系统的异常,同时也会增加额外的维护成本。
 
适用场景:
- 对象池:当需要频繁创建和销毁相似的对象时,可以使用享元模式将这些对象缓存在一个池中,以便重复使用。这样可以减少对象的创建和销毁成本,提高性能。
 - 文字编辑器:在文字编辑器中,每个字符都可以作为一个独立的对象来表示。但对于相同的字符,我们不必为每个出现的位置都创建一个新对象,而是可以共享同一个对象实例,从而节省内存空间。
 - 缓存系统:在缓存系统中,经常需要缓存大量的数据对象。通过使用享元模式,可以共享相同的数据对象,减少内存占用,并提高缓存的效率。
 - 游戏开发:在游戏中,特别是大规模多人在线游戏(MMOG)中,存在大量相似的对象,如玩家、怪物、道具等。通过使用享元模式,可以共享这些相似对象之间的公共数据,并且只需存储各个对象的变化部分,从而节省内存占用。
 
一、通过简单的示例代码实现享元模式
如下示例代码,通过一个字典来存储类的实例,如果 key 标识的实例第二次调用时,就直接从字典中取,不再重新创建:
// 测试一下
class Program
{
    static void Main(string[] args)
    {
        Flyweight flyweight = FlyweightFactory.GetFlyweight("Flyweight");
        Flyweight flyweight1 = FlyweightFactory.GetFlyweight("Flyweight1");
        Flyweight flyweight2 = FlyweightFactory.GetFlyweight("Flyweight2");
        flyweight.Operation();
        flyweight1.Operation();
        flyweight2.Operation();
        Console.ReadLine();
    }
}
public class FlyweightFactory
{
    private static Dictionary<string, Flyweight> flyweightDictionary = new Dictionary<string, Flyweight>();
    public static Flyweight GetFlyweight(string key)
    {
        if (flyweightDictionary.ContainsKey(key))
        {
            return flyweightDictionary[key];
        }
        else
        {
            switch (key)
            {
                case "Flyweight1":
                    ConcreteFlyweight1 flyweight1 = new ConcreteFlyweight1();
                    flyweightDictionary[key] = flyweight1;
                    return flyweight1;
                case "Flyweight2":
                    ConcreteFlyweight2 flyweight2 = new ConcreteFlyweight2();
                    flyweightDictionary[key] = flyweight2;
                    return flyweight2;
                default:
                    Flyweight flyweight = new Flyweight();
                    flyweightDictionary[key] = flyweight;
                    return flyweight;
            }
        }
    }
}
public class Flyweight
{
    public virtual void Operation()
    {
        Console.WriteLine("Operation is performed by Flyweight.");
    }
}
public class ConcreteFlyweight1 : Flyweight
{
    public override void Operation()
    {
        Console.WriteLine("ConcreteFlyweight1 is performing the operation.");
    }
}
public class ConcreteFlyweight2 : Flyweight
{
    public override void Operation()
    {
        Console.WriteLine("ConcreteFlyweight2 is performing the operation.");
    }
}

若后续需要添加新的享元实例ConcreteFlyweight3,就可以直接继承类Flyweight,但同时也需要在FlyweightFactory工厂类中添加对应的实例判断代码。
二、结构
根据上一章节中的示例代码,可以得结构图:

Flyweight:描述一个接口,通过这个接口 flyweight 可以接受并作用于外部状态。
ConcreteFlyweight:实现 Flyweight 接口,并为内部状态(如果有的话)增加存储空间。Concrete-Flyweight 对象是可共享的。它所存储的状态必须是内部的,即它必须独立于 ConcreteFlyweight 对象的场景。
FlyweightFactory:创建并管理flyweight 对象;确保合理地共享 flyweight。当用户请求一个 flyweight 时,FlyweightFactory 对象提供一个已创建的实例或者创建一个(如果不存在的话)。
Client:维持一个对 flyweight 的引用;计算或存储一个或多个 flyweight 的外部状态。
三、相关模式
Flyweight 享元模式通常和 Composite 组合模式结合起来,用共享叶结点的有向无环图实现一个逻辑上的层次结构。
通常,最好用 flyweight 实现 State 状态模式和Strategy 策略模式对象。
Flyweight 享元模式简介与 C# 示例【结构型6】【设计模式来了_11】的更多相关文章
- Flyweight享元模式(结构型模式)
		
1.面向对象的缺点 虽然OOP能很好的解决系统抽象的问题,并且在大多数的情况下,也不会损失系统的性能.但是在某些特殊的业务下,由于对象的数量太多,采用面向对象会给系统带来难以承受的内存开销.示例代码如 ...
 - Flyweight 享元模式 MD
		
享元模式 简介 在JAVA语言中,String类型就是使用了享元模式,JAVA中的字符串常量都是存在常量池中的,JAVA会确保一个字符串常量在常量池中只有一个拷贝,避免了在创建N多相同对象时所产生的不 ...
 - Java设计模式:Flyweight(享元)模式
		
概念定义 享元(Flyweight)模式运用共享技术高效地支持大量细粒度对象的复用. 当系统中存在大量相似或相同的对象时,有可能会造成内存溢出等问题.享元模式尝试重用现有的同类对象,如果未找到匹配的对 ...
 - 20、FlyWeight 享元模式
		
池化的思想 1.Flyweight享元模式 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用.由于享元模式要求能够共享的对象必 ...
 - C++设计模式-Flyweight享元模式
		
Flyweight享元模式 作用:运用共享技术有效地支持大量细粒度的对象. 内部状态intrinsic和外部状态extrinsic: 1)Flyweight模式中,最重要的是将对象分解成intrins ...
 - 设计模式之flyweight享元模式
		
运用共享技术支持大量细粒度对象的使用 Flyweight模式(享元) Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模 ...
 - 设计模式11: Flyweight 享元模式(结构型模式)
		
Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...
 - Flyweight(享元模式)
		
import java.util.Hashtable; /** * 享元模式 * @author TMAC-J * 享元模式一般和工厂模式一起使用,但此处为了更好说明,只用享元模式 * 定义:享元模式 ...
 - 设计模式(十二): Flyweight享元模式 -- 结构型模式
		
说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面 ...
 - 二十、Flyweight 享元模式
		
原理: 代码清单: BigChar public class BigChar { //字符名称 private char charname; //大型字符 # . \n 组成 private Stri ...
 
随机推荐
- SketchUp Pro 2023 下载和安装教程
			
SketchUp Pro 2023 下载和安装教程 下载链接 123云盘:https://www.123pan.com/s/JyAKVv-NTXB.html 安装教程 演示操作系统:Windows 1 ...
 - React组件设计之性能优化篇
			
我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品.我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值. 本文作者:空山 前言 由于笔者最近在开发中遇到了一个重复渲染导致子组 ...
 - Django: 后台常用操作
			
指定状态码 return JsonResponse(data, status=201) Djano删除数据库 删除对应数据库后,删除对应文件 删除对应的记录 Django后台管理 创建超级管理员 py ...
 - windows安装uwsgi报错 AttributeError: module 'os' has no attribute 'uname'
			
Win10系统不支持安装UWSGI, 不用尝试了 安装 pip install uwsgi windows安装报错 AttributeError: module 'os' has no attribu ...
 - 如何配置Linux的yum源
			
一.配置本地yum源 1.挂载光盘 a.建目录 #mkdir /media/cdrom b.挂载光盘 #mount /media/sr0 /media/cdrom c.挂载本地iso文件 #mount ...
 - 我通过 tensorflow 预测了博客的粉丝数
			
前言: 由于最近接触了 tensorflow.js,出于试一下的心态,想通过线性回归预测一下博客的粉丝走向和数量,结果翻车了.虽然场景用错地方,但是整个实战方法用在身高体重等方面的预测还是有可行性,所 ...
 - 解读 --- System.Windows.Forms.Timer是前台线程吗?
			
引言 今天同事问了我一个问题,System.Windows.Forms.Timer是前台线程还是后台线程,我当时想的是它是跟着UI线程一起结束的,应该是前台线程吧? 我确实没有仔细研究过他们的异同,所 ...
 - Java NIO 图解 Netty 服务端启动的过程
			
一.启动概述 了解整体Netty常用的核心组件后,并且对比了传统IO模式.在对比过程中,找到了传统IO对应Netty中是如何实现的.最后我们了解到在netty中常用的那些组件. 本文在了解下这些核心组 ...
 - Codeforces 1462E2 Close Tuples (hard version)
			
题意 给一个长度为\(n\)的数组,取\(m\)个数字,其中最大值最小值相差不大于\(k\),问这种方式有多少种,答案\(\mod 10^9+7\). 分析 通过简单版本大概了解了这题要枚举最小值来判 ...
 - CodeForces 1343D Constant Palindrome Sum
			
题意 多组样例 给一个长度为\(n\)(\(n\)一定为偶数)的数组\(a[]\),给一个正整数\(k\),保证数组内元素为小于等于\(k\)的正整数,你可以每次将数组的一个元素变为小于等于\(k\) ...