.NET设计模式(13):享元模式(Flyweight Pattern)
2009-02-05 13:07
375 查看
.NET设计模式(13):享元模式(Flyweight Pattern)
享元模式(Flyweight Pattern)
——.NET设计模式系列之十三Terrylee,2006年3月
摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题。但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价。那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面向对象的方式进行操作?
本文试图通过一个简单的字符处理的例子,运用重构的手段,一步步带你走进Flyweight模式,在这个过程中我们一同思考、探索、权衡,通过比较而得出好的实现方式,而不是给你最终的一个完美解决方案。
主要内容:
1. Flyweight模式解说
2..NET中的Flyweight模式
3.Flyweight模式的实现要点
……
概述
面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题。但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价。那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面向对象的方式进行操作?
意图
运用共享技术有效地支持大量细粒度的对象。[GOF 《设计模式》]
结构图
// "Charactor"
public abstract class Charactor
// "CharactorA"
public class CharactorA : Charactor
// "CharactorB"
public class CharactorB : Charactor
// "CharactorC"
public class CharactorC : Charactor
// "Charactor"
public abstract class Charactor
// "CharactorA"
public class CharactorA : Charactor
// "CharactorB"
public class CharactorB : Charactor
// "CharactorC"
public class CharactorC : Charactor
// "CharactorFactory"
public class CharactorFactory
public class Program
// "Charactor"
public abstract class Charactor
// "CharactorA"
public class CharactorA : Charactor
// "CharactorB"
public class CharactorB : Charactor
// "CharactorC"
public class CharactorC : Charactor
// "CharactorFactory"
public class CharactorFactory
public class Program
// "CharactorFactory"
public class CharactorFactory
public class Program
{
public static void Main(string[] args)
{
string s1 = "abcd";
string s2 = "abcd";
Console.WriteLine(Object.ReferenceEquals(s1,s2));
Console.ReadLine();
}
}
可以看到,输出的结果为True。但是大家要注意的是如果再有一个字符串s3,它的初始值为“ab”,再对它进行操作s3 = s3 + “cd”,这时虽然s1和s3的值相同,但是它们的引用是不同的。关于String的详细情况大家可以参考SDK,这里不再讨论了。
效果及实现要点
1.面向对象很好的解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。
2.Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象状态的处理。
3.享元模式的优点在于它大幅度地降低内存中对象的数量。但是,它做到这一点所付出的代价也是很高的:享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。另外它将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。
适用性
当以下所有的条件都满足时,可以考虑使用享元模式:
1、 一个系统有大量的对象。
2、 这些对象耗费大量的内存。
3、 这些对象的状态中的大部分都可以外部化。
4、 这些对象可以按照内蕴状态分成很多的组,当把外蕴对象从对象中剔除时,每一个组都可以仅用一个对象代替。
5、 软件系统不依赖于这些对象的身份,换言之,这些对象可以是不可分辨的。
满足以上的这些条件的系统可以使用享元对象。最后,使用享元模式需要维护一个记录了系统已有的所有享元的表,而这需要耗费资源。因此,应当在有足够多的享元实例可供共享时才值得使用享元模式。
总结
Flyweight模式解决的是由于大量的细粒度对象所造成的内存开销的问题,它在实际的开发中并不常用,但是作为底层的提升性能的一种手段却很有效。
参考资料
Erich Gamma等,《设计模式:可复用面向对象软件的基础》,机械工业出版社
Robert C.Martin,《敏捷软件开发:原则、模式与实践》,清华大学出版社
阎宏,《Java与模式》,电子工业出版社
Alan Shalloway James R. Trott,《Design Patterns Explained》,中国电力出版社
MSDN WebCast 《C#面向对象设计模式纵横谈(12):Flyweight享元模式(结构型模式)》
http://www.dofactory.com/
相关文章推荐
- .NET设计模式(13):享元模式(Flyweight Pattern)
- 设计模式学习笔记(13)——享元模式
- java学习笔记-设计模式13(享元模式)
- 设计模式(13)-享元模式(Flyweight)
- 设计模式(13)--享元模式
- java/android 设计模式学习笔记(13)---享元模式
- 设计模式学习笔记(13)——享元模式
- 步步为营 .NET 设计模式学习笔记 十七、Flyweight(享元模式)
- 设计模式(13) 享元模式(简单入门 结构模式)
- 13、C语言和设计模式(享元模式)
- 步步为营 .NET 设计模式学习笔记 十七、Flyweight(享元模式)
- java设计模式13_享元模式
- 设计模式之13--享元模式
- 步步为营 .NET 设计模式学习笔记 十七、Flyweight(享元模式)
- 设计模式--13、享元模式
- .NET设计模式-享元模式(Flyweight Pattern)
- 设计模式(13)享元模式--结构型
- Java/Android 设计模式系列(13)--享元模式
- Java设计模式笔记之享元模式
- * 24种设计模式——享元模式