设计模式系列享元模式Word文档格式.docx
《设计模式系列享元模式Word文档格式.docx》由会员分享,可在线阅读,更多相关《设计模式系列享元模式Word文档格式.docx(11页珍藏版)》请在冰豆网上搜索。
![设计模式系列享元模式Word文档格式.docx](https://file1.bdocx.com/fileroot1/2022-11/23/cd6d12bf-1ed9-4a15-818c-a9bae4937f53/cd6d12bf-1ed9-4a15-818c-a9bae4937f531.gif)
使用享元模式前:
使用享元模式后:
通过上图我们可以大概的看出享元模式的目的是什么,本篇将会从以下几点出发,讲述享元模式的应用。
1、享元模式的特点和场景。
2、享元模式的经典实现。
3、享元模式的其他方案。
4、享元模式小结。
下面我们来看下享元模式的类图吧:
三、本文大纲
a、上篇回顾。
b、摘要。
c、本文大纲。
d、享元模式的特点及使用场景。
e、享元模式的经典实现。
f、享元模式的其他方案。
g、享元模式使用总结。
h、系列进度。
i、下篇预告。
四、享元模式的特点及使用场景
4.1、享元模式的特点
享元模式的意图是通过共享有效支持大量细粒度的对象,来提供应用程序的性能,节省系统中重复创建对象实例的性能消耗,这个怎么理解呢?
其实就是以下几点的含义:
1、当我们系统中某个对象类型的实例较多的情况。
2、并且要求这些实例进行分类后,发现真正有区别的分类很少的情况。
例如我们的生活中很多的场景,我们在使用拼音输入的法的时候,如果说我们每个字都是new一个对象实例的操作的话,那么内存中的实例就太可
怕,这个时候,我们是不是可以考虑将这些重复的字体在内存中只是创建一次,而是通过复用对象的形式,来组织一些可能有多个字符重复的内容呢?
也许这是一个不错的主意,我们来看看这个示例的过程吧。
4.2、享元模式的使用场景
1、当我们发现某个类型的对象有大量的实例时,我们是否可以对这些实例进行分类,经过分类后,我们发现只有很少的类别的情况下。
2、我们发现通过使用享元模式后能够提高系统的性能和不会带来更多的复杂度时。
享元模式一般是给出本地内存资源节省的一个方案,并不适合互联网上的分布式应用的情况,不过享元模式对于排他性的要求资源的控制,是个不
错的选择的。
五、享元模式的经典实现
我们下面来根据上面的我们对输入法中的字体来进行分析,给出相关的示例代码:
字体类型的基类:
publicclassFontBase
{
privateList<
string>
font=newList<
();
privatestringfontName;
publicFontBase(stringname)
this.fontName=name;
}
publicFontBaseAddFont(stringfont)
this.font.Add(font);
returnthis;
publicvirtualstringFontName
get
returnthis.fontName;
}
具体的文字类型类:
publicclassChineseFont:
FontBase
publicChineseFont()
:
base("
ChineseFont"
)
base.AddFont("
);
publicclassEnglishFont:
publicEnglishFont()
EnglishFont"
具体的创建工厂类:
publicclassFontFactory
private
Dictionary<
string,FontBase>
fonts=newDictionary<
public
FontBaseCreate(stringname)
FontBasefontBase=fonts[name];
if(fontBase!
=null)
returnfontBase;
fontBase=(FontBase)Activator.CreateInstance(Type.GetType(name));
通过上面实例的讲解我们知道,我们通过缓存对象类型的形式来控制对象实例的创建过程,经典的模式中没有体现共享的状态,比如说我们在外部可能对于
享元对象来说是不共享的,内部是共享的。
下面我们来看看享元模式的变种吧。
六、享元模式的其他方案
对于上面的经典方案带来的问题,可能我们需要更好的考虑,我们如何应对多种对象类型,我们如何管理并共享这些对象实例,这些都是我们需要考虑的问
题,经过上面的思考,我们这里可以参考我们平时开发的ORM中的连接池的思路,我们这里对享元模式提供-对象池的技术。
我们在配置文件中控制对象池中的某个类型对象实例的数量,对象的生命周期的时间,默认初始化多少个对象实例,以提前准备,为后续的使用提供服务。
我们这里可以设计出这个专门的对象池,我们可以提供如下的功能:
1、根据对象类型动态的创建对象实例。
2、根据对象池中的配置,在对象池中找到空闲的实体提供给程序调用,减少创建对象的次数。
3、我们需要设计每个类型的缓冲池,通过把对象进行缓存,提供性能。
如果对象池中的对象长期不会调用,那么我们会提供一个销毁对象的机制。
我们来看看对象池的设计结构吧:
通过上面的几个组件,来协调完成对象池的工作。
这里给出相关的示例代码:
我们先给出配置文件配置缓冲池的配置信息:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<
xmlversion="
1.0"
encoding="
utf-8"
?
>
Cache>
ObjectSectionname="
"
type="
/>
ObjectCache>
objectname="
max="
timeout="
/>
/ObjectCache>
/Cache>
我们来看看具体的工厂类:
DIVclass=cnblogs_Highlighter>
PREclass=brush:
html>
publicclassObjectFactory
{
publicstaticTBuild<
T>
()whereT:
class,new()
returnnewT();
}
/PRE>
/DIV>
我们来看看具体的缓存类:
18
19
20
21
22
<
publicclassObjectCache
privatestaticDictionary<
Type,object>
cache=null;
publicstaticObjectCache()
cache=newDictionary<
publicvoidCache<
(Titem)
cache.Add(typeof(T),item);
publicvoidGetObjectFromCache<
(outTitem)
if(cache[typeof(T)]!
item=cache[typeof(T)];
七、享元模式使用总结
享元模式的主旨意在通过共享对象节省总体资源,不过共享对象将导致资源访问上的一些问题,包括对象实例的销毁,还包括线程间的共享和线程
内的共享是不同的,我们知道,一般线程退出的时候,会自动释放线程内部的申请的资源,.NET会自动通过GC来回收,但是对于线程间共享的对象也
许不会自动回收,这些内容需要宿主进程来进行回收,当然可能这些我们也可以通过对象池来完成这样的回收机制。
或者说也可以参考操作系统中的
队列的情况,通过回调函数来通知进行对象的回收等。
我们在对于项目中需要大量实例对象的创建工作的时候,我们就考虑一下是不是需要享元模式的
应用了,希望大家能在项目中找到合适的切入点,使用合适的模式来提高程序的适应性和健壮性。
由于本人水平有限,不足或者错误之处,还请大家批
评指出。
八、系列进度
创建型
1、系统架构技能之设计模式-单件模式
2、系统架构技能之设计模式-工厂模式
3、系统架构技能之设计模式-抽象工厂模式
4、系统架构技能之设计模式-创建者模式
5、系统架构技能之设计模式-原型模式
结构型
1、系统架构技能之设计模式-组合模式
2、系统架构技能之设计模式-外观模式
3、系统架构技能之设计模式-适配器模式
4、系统架构技能之设计模式-桥模式
5、系统架构技能之设计模式-装饰模式
6、系统架构技能之设计模式-享元模式
7、系统架构技能之设计模式-代理模式
行为型
1、系统架构技能之设计模式-命令模式
2、系统架构技能之设计模式-观察者模式
3、系统架构技能之设计模式-策略模式
4、系统架构技能之设计模式-职责模式
5、系统架构技能之设计模式-模板模式
6、系统架构技能之设计模式-中介者模式
7、系统架构技能之设计模式-解释器模式