〇、简介

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】的更多相关文章

  1. Flyweight享元模式(结构型模式)

    1.面向对象的缺点 虽然OOP能很好的解决系统抽象的问题,并且在大多数的情况下,也不会损失系统的性能.但是在某些特殊的业务下,由于对象的数量太多,采用面向对象会给系统带来难以承受的内存开销.示例代码如 ...

  2. Flyweight 享元模式 MD

    享元模式 简介 在JAVA语言中,String类型就是使用了享元模式,JAVA中的字符串常量都是存在常量池中的,JAVA会确保一个字符串常量在常量池中只有一个拷贝,避免了在创建N多相同对象时所产生的不 ...

  3. Java设计模式:Flyweight(享元)模式

    概念定义 享元(Flyweight)模式运用共享技术高效地支持大量细粒度对象的复用. 当系统中存在大量相似或相同的对象时,有可能会造成内存溢出等问题.享元模式尝试重用现有的同类对象,如果未找到匹配的对 ...

  4. 20、FlyWeight 享元模式

    池化的思想 1.Flyweight享元模式 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用.由于享元模式要求能够共享的对象必 ...

  5. C++设计模式-Flyweight享元模式

    Flyweight享元模式 作用:运用共享技术有效地支持大量细粒度的对象. 内部状态intrinsic和外部状态extrinsic: 1)Flyweight模式中,最重要的是将对象分解成intrins ...

  6. 设计模式之flyweight享元模式

    运用共享技术支持大量细粒度对象的使用 Flyweight模式(享元) Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模 ...

  7. 设计模式11: Flyweight 享元模式(结构型模式)

    Flyweight 享元模式(结构型模式) 面向对象的代价 面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能.但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系 ...

  8. Flyweight(享元模式)

    import java.util.Hashtable; /** * 享元模式 * @author TMAC-J * 享元模式一般和工厂模式一起使用,但此处为了更好说明,只用享元模式 * 定义:享元模式 ...

  9. 设计模式(十二): Flyweight享元模式 -- 结构型模式

    说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面 ...

  10. 二十、Flyweight 享元模式

    原理: 代码清单: BigChar public class BigChar { //字符名称 private char charname; //大型字符 # . \n 组成 private Stri ...

随机推荐

  1. sshpiper 在 Kubernetes 上的应用

    sshpiper 在 Kubernetes 上的应用 介绍 GitHub Repo 一个反向代理目标服务器的 proxy,客户端想请求某个 ssh 服务器,直接请求的是 sshpiper 服务,再经由 ...

  2. 【渗透测试】Cobalt Strike制作钓鱼邮件渗透Windows

    目标 在kali中使用Cobalt Strike制作钓鱼邮件,对Windows进行渗透 机器环境 kali(服务端):192.168.175.129 win11(攻击机):192.168.175.12 ...

  3. RestSharp HTTP请求库

    官方文档:https://restsharp.dev/intro.html#introduction c# RestSharp(http请求):https://blog.csdn.net/czjnoe ...

  4. IE浏览器不支持TextDecoder()的问题

    IE浏览器不支持TextDecoder()方法,因此在进行Arrbuffer转string或中文时,出现未定义的错误.通过网上查找方法,可以通过引用第三方库进行解决. github地址:https:/ ...

  5. 全局多项式(趋势面)与IDW逆距离加权插值:MATLAB代码

      本文介绍基于MATLAB实现全局多项式插值法与逆距离加权法的空间插值的方法,并对不同插值方法结果加以对比分析. 目录 1 背景知识 2 实际操作部分 2.1 空间数据读取 2.2 异常数据剔除 2 ...

  6. 接口自动化测试项目 | IHRM登录接口自动化测试

    项目内容如下: ### 需求- 地址:http://ihrm-java.itheima.net/#/login- 测试接口: - 登录接口:针对登录的13个cases### 技术 - V1:pytho ...

  7. TIKZ全局样式设置

    tikz绘图引擎 TIKZ绘图引擎是基于tex实现,代码极其复杂,每次编写都要单独设置样式,甚是繁琐,如何能够全局设置呢? \begin{tikzpicture}[ auto, % 决策结点 deci ...

  8. Spring Boot 中使用 Poi-tl 渲染数据并生成 Word 文档

    本文 Demo 已收录到 demo-for-all-in-java 项目中,欢迎大家 star 支持!后续将持续更新! 前言 产品经理急冲冲地走了过来.「现在需要将按这些数据生成一个 Word 报告文 ...

  9. 如何保持 SSH 会话不中断?

    哈喽大家好,我是咸鱼 不知道小伙伴们有没有遇到过下面的情况: 使用终端(XShell.secureCRT 或 MobaXterm 等)登录 Linux 服务器之后如果有一段时间没有进行交互,SSH 会 ...

  10. Electron包装网站的问题

    原文链接 原文链接 Preface 最近尝试了很多不错的在线工具,只是每次都要进入网站,有点麻烦,于是想到之前了解过的electron,尝试一下打包成本地应用. Contents 1.下载所有源文件 ...