c#设计模式系类:亨元模式
一、引言
在软件开发过程中,如果我们需要重复使用某个对象的时候,如果我们重复地使用new创建这个对象的话,这样我们在内存就需要多次去申请内存空间了,这样可能出现内存使用越来越多的情况,这样的问题是非常严重,然而亨元模式可以解决这个问题,下面我们一起具体看看亨元模式是如何解决这个问题的。
二、享元模式的详细介绍
既然亨元模式可以解决重复使用new创建对象的问题,下面让我们分析下如何去解决上面那个问题,既然都是同一个对象,能不能只创建一个对象,然后下次需要创建这个对象的时候,让它直接用已经创建好了的对象就好了呢,也就是说让一个对象共享。这个也是亨元模式的实现精髓所在。
2.1 定义
介绍完享元模式的精髓之后,让我们具体看看享元模式的正式定义:
亨元模式——利用共享技术有效地支持大量细粒度的类实例来表示数据,亨元模式可以避免大量相识类的开销,在软件开发过程中如果需要大量细粒度的类实例来表示数据,而这些实例除了几个参数外基本相同,这时候就可以使用亨元模式来大幅度减少需要类的实例数量。如果能把这些参数(指的这些类实例的不同参数)移动到类实例外面,在方法调用时将他们传入尽量,这样就可以通过共享大幅度减少单个实例的数目,然而我们把类实例外面的参数称为亨元对象的外部状态,把亨元对象内部参数称为内部状态,
- 内部状态:在亨元对象的内部,并且不会随着环境的改变而改变的共享部分
- 外部对象:随环境的变化而改变的,部可以共享的部分。
2.2 亨元模式结构图

2.3 亨元模式的组成
- 抽象亨元角色(Flyweight):此角色是所有的具体亨元类的基类,为这些类规定出需要实现的公共接口,那些需要外部状态的操作可以通过调用方法已参数形式传递。
- 具体亨元角色(ConcreteFlyweight):实现抽象亨元角色所规定的接口,如果又内部状态的化,可以在类内部定义。
- 亨元工厂角色(FlyweightFactory):本角色负责创建和管理亨元角色,本角色保证亨元对象可以被共享,当一个客户端调用一个亨元对象的时候,亨元工厂角色检查系统是否已经有一个符合的亨元对象,如果已经存在,就返回亨元对象,如果不存在就重新创建一个亨元对象
- 客户端角色(Client):本角色需要存储亨元对象的外部状态
2.4亨元模式代码实现
Flyweight类,它是所有具体亨元类的超类或接口,通过这个接口,Flyweight可以接受并作用于外部状态

public abstract class Flywieght
{
public abstract void Operation(int extrinsicstate);
}
ConcreteFlyweight是继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间。

public class ConcreteFlyweight:Flywieght
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("具体的"+extrinsicstate);
}
}
UnsharedConcreteFlyweight是 指那些不需要共享的Flyweight子类,因为Flyweight接口让共享成为可能,但它并不强制共享

public class UnsharedConcreteFlyweight:Flywieght
{
public override void Operation(int extrinsicstate)
{
Console.WriteLine("不共享的具体Flywieght"+extrinsicstate);
}
}
FlyweightFactory,是一个亨元工厂,用来创建并管理Flyweight对象,它主要是用来确保合理的共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在)

public class FlyweightFactory
{
private Hashtable flyweights = new Hashtable(); public FlyweightFactory()
{
flyweights.Add("X",new ConcreteFlyweight());
flyweights.Add("Y", new ConcreteFlyweight());
flyweights.Add("Z", new ConcreteFlyweight());
}
public Flywieght GetFlyweight(string key)
{
return ((Flywieght)flyweights[key]) ;
}
}
客户端代码

class Program
{
static void Main(string[] args)
{
int extrinsincstate = 10;
FlyweightFactory f = new FlyweightFactory(); Flywieght fx = f.GetFlyweight("X");
fx.Operation(--extrinsincstate); Flywieght fy = f.GetFlyweight("Y");
fy.Operation(--extrinsincstate); Flywieght fz = f.GetFlyweight("Z");
fz.Operation(--extrinsincstate); UnsharedConcreteFlyweight uf = new UnsharedConcreteFlyweight();
uf.Operation(--extrinsincstate); Console.Read();
}
}
结果表示

具体的9
具体的8
具体的7
不共享的具体Flywieght6
三、享元模式的实现要点:
面向对象很好地解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。
Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象状态的处理。
对象的数量太大从而导致对象内存开销加大——什么样的数量才算大?这需要我们仔细的根据具体应用情况进行评估,而不能凭空臆断。
- 享元模式的优点
- 享元模式的优点在于它能够极大的减少系统中对象的个数。
- 元模式由于使用了外部状态,外部状态相对独立,不会影响到内部状态,所以享元模式使得享元对象能够在不同的环境被共享。
- 享元模式的缺点
- 于享元模式需要区分外部状态和内部状态,使得应用程序在某种程度上来说更加复杂化了。
- 为了使对象可以共享,享元模式需要将享元对象的状态外部化,而读取外部状态使得运行时间变
- 在下面所有条件都满足时,可以考虑使用享元模式:
- 一个系统中有大量的对象;
- 这些对象耗费大量的内存;
- 这些对象中的状态大部分都可以被外部化
- 这些对象可以按照内部状态分成很多的组,当把外部对象从对象中剔除时,每一个组都可以仅用一个对象代替软件系统不依赖这些对象的身份,
满足上面的条件的系统可以使用享元模式。但是使用享元模式需要额外维护一个记录子系统已有的所有享元的表,而这也需要耗费资源,所以,应当在有足够多的享元实例可共享时才值得使用享元模式。
通过迭代来使用模式,别为了模式而模式
c#设计模式系类:亨元模式的更多相关文章
- Java设计模式之亨元模式
之前在项目中接触过亨元模式这一种设计模式,当时因为项目赶进度,因此只不过是大概的了解了一下,刚好今天有时间,就写一篇博客详细的学习一下亨元模式. 一.概念 运用共享技术有效的支持大量细粒度的对象.(来 ...
- 设计模式 -- 亨元模式(FlyWeight Pattern)
用来尽可能减少内存使用量,适用于存在大量重复对象的场景,达到对象共享,避免创建过多对象的效果,提升性能,避免内存溢出. 定义: 使用共享对象有效支持大量细粒度对象. 适用场景: 系统中存在大量相似对象 ...
- Java设计模式之《享元模式》及应用场景
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6542449.html 享元模式:"享"就是分享之意,指一物被众人共享, ...
- 面向对象设计模式之Flyweight享元模式(结构型)
动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行代价——主要指内存需求方面的代价.如何在避免大量细粒度对象问题的同 时,让外部客户程序仍然能够透明地使用面向对象的 ...
- 设计模式学习之享元模式(Flyweight,结构型模式)(20)
转:http://terrylee.cnblogs.com/archive/2006/03/29/361767.html 摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是 ...
- 设计模式学习心得<享元模式 Flyweight>
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式. 享元模式尝 ...
- C#设计模式之十一享元模式(Flyweight Pattern)【结构型】
一.引言 今天我们要讲[结构型]设计模式的第六个模式,该模式是[享元模式],英文名称是:Flyweight Pattern.还是老套路,先从名字上来看看.“享元”是不是可以这样理解,共享“单元”,单元 ...
- Java设计模式学习记录-享元模式
前言 享元模式也是一种结构型模式,这篇是介绍结构型模式的最后一篇了(因为代理模式很早之前就已经写过了).享元模式采用一个共享来避免大量拥有相同内容对象的开销.这种开销最常见.最直观的就是内存损耗. 享 ...
- 设计模式(11)--Flyweight(享元模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 2.模式特点: 享元模 ...
随机推荐
- 更改AD域安全策略-密码必须符合复杂性要求
在域环境中,修改域用户密码时,会提示不符合密码策略, 更改"本地安全策略"是不会对域产生任何的作用的. 上图中可以看,这里按钮都是灰色的! 下面这个步骤教你如何找到"域安 ...
- 为什么是static?
为什么是static因为系统开始执行一个程序前,并没有创建main()方法所在类的实例对象,它只能通过类名类调用主方法. public static void main(String args[])我 ...
- then()方法是异步执行
then()方法是异步执行 就是当.then()前的方法执行完后再执行then()内部的程序 这样就避免了,数据没获取到等的问题
- SPI子系统分析之三:驱动模块
内核版本:3.9.5 SPI核心层(平台无关) SPI子系统初始化的第一步就是将SPI总线注册进内核,并且在/sys下创建一个spi_master的类,以后注册的从设备都将挂接在该总线下. 下列函数位 ...
- Invoke and BeginInvoke(转载:http://www.cnblogs.com/worldreason/archive/2008/06/09/1216127.html)
一.为什么Control类提供了Invoke和BeginInvoke机制? 关于这个问题的最主要的原因已经是dotnet程序员众所周知的,我在此费点笔墨再次记录到自己的日志,以便日后提醒一下自己. 1 ...
- 【bzoj3239】Discrete Logging
[吐槽] 这题和[bzoj]2480一毛一样. 就是输入顺序和输出变了一下. 传送门:http://www.cnblogs.com/chty/p/6043707.html
- C语言中static修饰符的意义
在C语言中,static通常有2种含义:1)定义变量的生命周期:2)定义变量或者函数的作用域. 变量的生命周期是指,相对于程序运行的进程生命周期,变量存在的时间段.变量的生命周期由变量的存储类型(位置 ...
- 安装操作系统CentOS-7.x
一.创建虚拟机 使用VMware Fusion创建虚拟机 二.系统安装 为了统一环境,保证实验的通用性,将网卡名称设置为eth*,不使用CentOS 7默认的网卡命名规则.所以需要在安装的时候,增加内 ...
- linux常用的一些命令行操作(ubuntu)
软件安装 sudo apt-get install xxx 压缩和解压缩 1. *.tar 用 tar –xvf 解压 2. *.gz 用 gzip -d或者gunzip 解压 3. *.tar.gz ...
- web.xml配置详解[转]
引文: 对于一个J2EE领域的程序员而言,基本上每天都会和web应用打交道. 什么是web应用?最简单的web应用什么样?给你一个web应用你该从何入手? 1.什么是web应用? web应用是一种可以 ...