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.模式特点: 享元模 ...
随机推荐
- Python之路,Day9 , IO多路复用(番外篇)
同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network IO. ...
- Elasticsearch-2.4.3的下载(图文详解)
第一步:进入Elasticsearch的官网 https://www.elastic.co/ 第二步:点击downloads https://www.elastic.co/downloads 第三步: ...
- Elasticsearch 搜索引擎
简介: Elasticsearch 是一个实时的分布式搜索和分析引擎.它可以帮助你用前所未有的速度去处理大规模数据.它可以用于全文搜索,结构化搜索以及分析. 分布式实时文件存储,并将每一个字段都 ...
- f.lux Ubuntu 下进行安装
这几天在搞Ubuntu 看的是我眼睛特痛,于是查了一下,有Linux 版的f.lux 于是我就行了一番的安装. 步骤 命令行 1. sudo add-apt-r ...
- GitHub个人使用入门
今天突然想起来了github 于是开始了入门之旅 如果你用过svn 那么你用起来感觉入门比较快的(至少我是这么感觉的)和在svn服务器上建项目的流程很像 每次修改代码之后提交的过程是: add, co ...
- Linux服务管理 systemctl命令详解
Linux服务器,服务管理--systemctl命令详解,设置开机自启动 syetemclt就是service和chkconfig这两个命令的整合 任务 旧指令 新指令 使某服务自动启动 ch ...
- (转)C#命名规范
C#命名规范 数据类型 数据类型简写 标准命名举例 Array arr arrShoppingList Boolean bln blnIsPostB ...
- spring boot aop打印http请求回复日志包含请求体
一.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- 【POJ1284】Primitive Roots
[题目大意] 给你一个素数n,求n的原根个数. [题解] 关于原根有一个定理: 定理:如果模有原根,那么它一共有个原根. 所以这题就是求phi[phi[n]] 很简单吧...(如果知道这个定理的话) ...
- [C++] c Struct VS c++ Struct
c Struct c语言生命变量要加上struct c语言结构体内部不能有函数 C语言结构体没有共有,私有和继承