系统架构技能之设计模式—享元模式

  一、上篇回顾

  通过上篇的讲述,我们知道装饰模式,特别适合对某个类型的对象,动态的增加新的职责,应用程序就像使用原来的对象一样使用对象新增的装饰后的功能,装 饰模式就好像是穿了一层层的外壳,这样的方式避免了通过继承来为类型添加新的职责的形式可取,通过继承的方式容易造成子类的膨胀,但是当装饰类太多的时 候,也是个难以维护的问题,至少是在装饰对象的时候,我们可能需要多步操作来完成对象的装饰,这时候我们可以同上面提出的改进的方案,来完成自动配置装饰 模式,记录操作模式的状态,可以进行有效的回滚操作,以完成撤销操作。

  我们先来回顾下装饰模式的使用场景:

      1、当我们需要为某个现有的对象,动态的增加一个新的功能或职责时,可以考虑使用装饰模式。

      2、适应于某个对象的职责经常发生变化或者经常需要动态的增加职责,避免因为这种为了适应这样的变化,而增加继承子类扩展的方式,因为这种方式为 造成,子类膨胀的速度过快,难以控制。

  二、摘要

  本篇我们将会讲述结构性模式中的另外一个非常有用的模式-享元模式,享元模式的特点是,复用我们内存中已存在的对象,降低系统创建对象实例的性能消耗。在.NET下的值类型和引用类型的内存分配机制,我这里就不做详细的讲解了,包括引用类型与值类型之间的装箱和拆箱的操作,这个具体的可以参考园子里面的关于这方面的文章的讨论。

  我们来给出个简单的享元模式的应用前后的对比图,大概我们就知道享元模式的重要作用了。

  我们这里以绘制一个有样式的字体来说明吧,有的时候我们想绘制一个纯色的文字,比如红色,那么我们可能需要创建很多的实例,通常来说,这些实例的差别不大,这个时候,我们可以考虑复用其中创建的某个实例,而不用去new这么多相同的对象,来完成这样的工作。我们下面以这个例子来说明,使用享元模式的前后对比的情况。

  使用享元模式前:    image

  使用享元模式后:    image

  通过上图我们可以大概的看出享元模式的目的是什么,本篇将会从以下几点出发,讲述享元模式的应用

  1、享元模式的特点和场景。

  2、享元模式的经典实现。

  3、享元模式的其他方案。

  4、享元模式小结。

  下面我们来看下享元模式的类图吧:

  三、本文大纲

       a、上篇回顾。

       b、摘要。

       c、本文大纲。

       d、享元模式的特点及使用场景。

       e、享元模式的经典实现。

       f、享元模式的其他方案。

       g、享元模式使用总结。

  四、享元模式的特点及使用场景

  4.1、享元模式的特点

  享元模式的意图是通过共享有效支持大量细粒度的对象,来提供应用程序的性能,节省系统中重复创建对象实例的性能消耗,这个怎么理解呢?其实就是以下几点的含义:

  1、当我们系统中某个对象类型的实例较多的情况。

  2、并且要求这些实例进行分类后,发现真正有区别的分类很少的情况。

      例如我们的生活中很多的场景,我们在使用拼音输入的法的时候,如果说我们每个字都是new一个对象实例的操作的话,那么内存中的实例就太可怕,这个时候,我们是不是可以考虑将这些重复的字体在内存中只是创建一次,而是通过复用对象的形式,来组织一些可能有多个字符重复的内容呢?也许这是一个不错的主意,我们来看看这个示例的过程吧。

image

  4.2、享元模式的使用场景

  1、当我们发现某个类型的对象有大量的实例时,我们是否可以对这些实例进行分类,经过分类后,我们发现只有很少的类别的情况下。

  2、我们发现通过使用享元模式后能够提高系统的性能和不会带来更多的复杂度时。

  享元模式一般是给出本地内存资源节省的一个方案,并不适合互联网上的分布式应用的情况,不过享元模式对于排他性的要求资源的控制,是个不错的选择的。

  五、享元模式的经典实现

  我们下面来根据上面的我们对输入法中的字体来进行分析,给出相关的示例代码:

字体类型的基类:
public class FontBase
{
private List<string> font = new List<string>();

private string fontName;
public FontBase(string name)
{
this.fontName = name;
}

public FontBase AddFont(string font)
{
this.font.Add(font);
return this;
}
public virtual string FontName
{
get
{
return this.fontName;
}
}
}
具体的文字类型类:
public class ChineseFont : FontBase
{
public ChineseFont()
:
base("ChineseFont")
{
base.AddFont("ChineseFont");
}
}
public class EnglishFont : FontBase
{
public EnglishFont()
:
base("EnglishFont")
{
base.AddFont("EnglishFont");
}
}
具体的创建工厂类:
public class FontFactory
{
private Dictionary<string, FontBase> fonts = new Dictionary<string, FontBase>();

public FontBase Create(string name)
{
FontBase fontBase
= fonts[name];
if (fontBase != null)
return fontBase;

fontBase
= (FontBase)Activator.CreateInstance(Type.GetType(name));

return fontBase;
}
}

it知识库系统架构技能之设计模式—享元模式,转载需保留来源!

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。