.NET设计模式(13):享元模式(Flyweight Pattern)
2007-11-21 16:49
387 查看
概述
面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题。但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价。那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面向对象的方式进行操作?
意图
运用共享技术有效地支持大量细粒度的对象。[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/
面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题。但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价。那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面向对象的方式进行操作?
意图
运用共享技术有效地支持大量细粒度的对象。[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、C语言和设计模式(享元模式)
- 设计模式(13) 享元模式(简单入门 结构模式)
- 步步为营 .NET 设计模式学习笔记 十七、Flyweight(享元模式)
- 设计模式之13--享元模式
- java设计模式13_享元模式
- .NET设计模式-享元模式(Flyweight Pattern)
- 设计模式--13、享元模式
- 步步为营 .NET 设计模式学习笔记 十七、Flyweight(享元模式)
- Java/Android 设计模式系列(13)--享元模式
- 设计模式(13)享元模式--结构型
- Android设计模式系列--之享元模式
- 步步为营 .NET 设计模式学习笔记系列总结