引言

在软件开发过程,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次地去申请内存空间了,这样可能会出现内存使用越来越多的情况,这样的问题是非常严重,然而享元模式可以解决这个问题,下面具体看看享元模式是如何去解决这个问题的。

享元模式的详细介绍

在前面说了,享元模式可以解决上面的问题了,在介绍享元模式之前,让我们先要分析下如果去解决上面那个问题,上面的问题就是重复创建了同一个对象,如果让我们去解决这个问题肯定会这样想:“既然都是同一个对象,能不能只创建一个对象,然后下次需要创建这个对象的时候,让它直接用已经创建好了的对象就好了”,也就是说——让一个对象共享。不错,这个也是享元模式的实现精髓所在。

定义

介绍完享元模式的精髓之后,让我们具体看看享元模式的正式定义:

享元模式——运用共享技术有效地支持大量细粒度的对象。享元模式可以避免大量相似类的开销,在软件开发中如果需要生成大量细粒度的类实例来表示数据,如果这些实例除了几个参数外基本上都是相同的,这时候就可以使用享元模式来大幅度减少需要实例化类的数量。如果能把这些参数(指的这些类实例不同的参数)移动类实例外面,在方法调用时将他们传递进来,这样就可以通过共享大幅度地减少单个实例的数目。(这个也是享元模式的实现要领),然而我们把类实例外面的参数称为享元对象的外部状态,把在享元对象内部定义称为内部状态。具体享元对象的内部状态与外部状态的定义为:

内部状态:在享元对象的内部并且不会随着环境的改变而改变的共享部分

外部状态:随环境改变而改变的,不可以共享的状态。

  • Flyweight----抽象享元角色
          简单的说就是一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口或实现。 
  • ConcreteFlyweight----具体享元角色
          具体的一个产品类,实现抽象角色定义的业务。该角色中需要注意的是内部状态处理应该与环境无关,不应该出现一个操作改       变了内部状态,同时修改了外面状态,这是绝对不允许的。 
  • unsharedConcreteFlyweight----不可共享的享元角色
         不存在外部状态或者安全要求(如线程安全)不能够使用共享技术的对象,该对象一般不会出现在享元工厂中。 
  • FlyweightFactory----享元工厂
         职责非常简单,就是构造一个池容器,同时提供从池中获得对象的方法。
 
具体实现代码如下:
   /// <summary>
/// 抽象享元角色
/// </summary>
public abstract class Flyweight
{
//内部状态
private string intrinsic;
//外部状态
protected readonly string Extrinsic;
//要求享元角色必须接受外部状态
public Flyweight(string _Extrinsic)
{
this.Extrinsic = _Extrinsic;
}
//定义业务操作
public abstract void operate();
public string Intrinsic
{
set
{
this.intrinsic = value;
}
get
{
return this.intrinsic;
}
}
}
/// <summary>
/// 具体享元角色
/// </summary>
public class ConcreteFlyweight1 : Flyweight
{
//接受外部状态
public ConcreteFlyweight1(string _Extrinsic)
: base(_Extrinsic)
{
}
//根据外部状态进行逻辑处理
public override void operate()
{
//业务逻辑
}
}
/// <summary>
/// 具体享元角色
/// </summary>
public class ConcreteFlyweight2 : Flyweight
{
//接受外部状态
public ConcreteFlyweight2(string _Extrinsic)
: base(_Extrinsic)
{
}
//根据外部状态进行逻辑处理
public override void operate()
{
//业务逻辑
}
}
/// <summary>
/// 享元工厂
/// </summary>
public class FlyweightFactory
{
//定义一个池容器
private static IDictionary<string, Flyweight> pool = new Dictionary<string, Flyweight>();
//享元工厂
public static Flyweight getFlyweight(string Extrinsic)
{
Flyweight flyweight = null;
if (pool.ContainsKey(Extrinsic))
{
flyweight = pool[Extrinsic];
}
else
{
flyweight = new ConcreteFlyweight1(Extrinsic);
pool[Extrinsic] = flyweight;
}
return flyweight;
}
}

享元模式的优缺点

分析完享元模式的实现之后,让我们继续分析下享元模式的优缺点:

优点:

  1. 降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。

缺点:

  1. 为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑更复杂,使系统复杂化。
  2. 享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。

使用场景

在下面所有条件都满足时,可以考虑使用享元模式:

  • 一个系统中有大量的对象;
  • 这些对象耗费大量的内存;
  • 这些对象中的状态大部分都可以被外部化
  • 这些对象可以按照内部状态分成很多的组,当把外部对象从对象中剔除时,每一个组都可以仅用一个对象代替
  • 软件系统不依赖这些对象的身份,

满足上面的条件的系统可以使用享元模式。但是使用享元模式需要额外维护一个记录子系统已有的所有享元的表,而这也需要耗费资源,所以,应当在有足够多的享元实例可共享时才值得使用享元模式。

结构型---享元模式(Flyweight Pattern)的更多相关文章

  1. 设计模式-11享元模式(Flyweight Pattern)

    1.模式动机 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题.创建那么多的对象将会耗费很多的系统资源,它是系统性能提高的一个瓶颈. 享元模式就是把相同或相似对象的公共部分提取出 ...

  2. 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  3. 二十四种设计模式:享元模式(Flyweight Pattern)

    享元模式(Flyweight Pattern) 介绍运用共享技术有效地支持大量细粒度的对象. 示例有一个Message实体类,某些对象对它的操作有Insert()和Get()方法,现在要运用共享技术支 ...

  4. 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern)

    原文:乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 享元模式(Flyweight Pattern) 作者:weba ...

  5. Java享元模式(Flyweight Pattern)

    享元模式(Flyweight Pattern)主要用于减少创建的对象数量,并减少内存占用并提高性能. 这种类型的设计模式属于结构模式,因为该模式提供了减少对象计数的方法,从而改善应用的对象结构. 享元 ...

  6. 【UE4 设计模式】享元模式 Flyweight Pattern

    概述 描述 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用. 由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻 ...

  7. 享元模式<Flyweight Pattern>

    1.What-是什么?   享元模式是一种轻量级的结构型模式.旨在以共享的方式高效的支持大量的细粒度对象的复用.要求能够共享的对象必须是细粒度对象,这些对象比较相似,状态变化小. 2.Why-为什么? ...

  8. 七个结构模式之享元模式(Flyweight Pattern)

    定义: 运用共享技术对大量细粒度对象的复用,这要求这些对象都很相似,状态变化很小.将这些对象的内部状态和外部状态进行区分,对于内部状态相同的只存储一个对象,而对不同的外部状态则采用不同的操作. 结构图 ...

  9. 享元模式(Flyweight Pattern)

    定义: 采用一个共享来避免大量拥有相同内容对象的开销.这种开销中最常见.直观的就是内存的损耗.享元模式以共享的方式高效的支持大量的细粒度对象. 享元的英文是flyweight,是一个来自体育方面的专业 ...

随机推荐

  1. Centos 安装 mysql yum

    http://www.cnblogs.com/007sx/p/7083143.html https://www.linode.com/docs/databases/mysql/how-to-insta ...

  2. 【python-appium】模拟手机按键搜索异常

    执行代码的过程中运行self.driver.press_keycode(84)设备没反映,则需要关闭#desired_caps["unicodeKeyboard"] = " ...

  3. winform中TextBox只能输入字母

    private void txtTestPerson_KeyPress(object sender, KeyPressEventArgs e) { if ((e.KeyChar >= 'a' & ...

  4. Python之配置日志的几种方式(logging模块)

    原文:https://blog.csdn.net/WZ18810463869/article/details/81147167 作为开发者,我们可以通过以下3种方式来配置logging: 1)使用Py ...

  5. 【Solidity】学习(3)

    函数 重定义 不支持重定义,会在编译时候报错 pragma solidity ^0.4.0; contract test { uint public a =100; function changeA ...

  6. 《C# 从现象到本质》出版,免费送书10本

    我的第一本书<C# 从现象到本质>已于近日正式在京东和淘宝天猫上开始销售了.至此,我的图书写作和出版活动正式告一段落.图书销售网址见下. 试读样章 京东 天猫 从看书到写书 借着图书出版之 ...

  7. 升讯威微信营销系统开发实践:所见即所得的微官网( 完整开源于 Github)

    GitHub:https://github.com/iccb1013/Sheng.WeixinConstruction因为个人精力时间有限,不会再对现有代码进行更新维护,不过微信接口比较稳定,经测试至 ...

  8. navicat 几个 可用的东西

    1.常用的 表格 一启动 就进入的某某连接某某数据库某某表 2. 结构 比对(菜单栏 “工具里面”) 3.数据对比 同上 4.保持连接 5.全局查询 在工具中查找 ------在数据库或模式中查找

  9. 吴恩达机器学习笔记5-梯度下降I(Gradient descent intuition)

    梯度下降是一个用来求函数最小值的算法,我们将使用梯度下降算法来求出代价函数

  10. redis5.0新特性

    1. redis5.0新特性 1.1. 新的Stream类型 1.1.1. 什么是Stream数据类型 抽象数据日志 数据流 1.2. 新的Redis模块API:Timers and Cluster ...