设计模式:享元模式(Flyweight)

定   义:运用共享技术有效地支持大量细粒度的对象。

结构图

内部状态:在享元对象内部并且不会随环境而改变的共享部分。

外部状态:随环境改变而改变的、不可共享的状态。

Flyweight类,具体享元类的超类和接口,通过这个接口,Flyweight可以接受并作用于外部状态。

 abstract class Flyweight
    {
        public abstract void Operation(int extrinsicstate);
    }
View Code

ConcreteFlyweight继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间。

 class ConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("具体Flyweight:" + extrinsicstate);
        }
    }
View Code

UnshareFlyweight是指那些不需要共享的Flyweight子类。因为Flyweight接口共享成为可能,但它并不强制共享。

 class UnShareConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);
        }
    }
View Code

FlyweightFactory,是一个共享工厂,用来创建并管理Flyweight对象。它主要确保合理地共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个(如果不存在)。

 class FlyweightFactory
    {
        private Hashtable flyweihts = new Hashtable();

        public Flyweight GetFlyweight(string key)
        {
            if (!flyweihts.ContainsKey(key))
            {
                flyweihts.Add(key, new ConcreteFlyweight());
            }

            return (Flyweight)flyweihts[key];
        }
    }
View Code

客户端调用

            int extrinsicstate = 22;
            FlyweightFactory f = new FlyweightFactory();

            Flyweight fx = f.GetFlyweight("X");
            fx.Operation(--extrinsicstate);

            Flyweight fy = f.GetFlyweight("Y");
            fx.Operation(--extrinsicstate);

            Flyweight fz = f.GetFlyweight("Z");
            fx.Operation(--extrinsicstate);

            UnShareConcreteFlyweight uf = new UnShareConcreteFlyweight();
            uf.Operation(--extrinsicstate);
View Code

结果

享元模式的优点:

          大幅度地降低内存中对象的数量。

享元模式的缺点:

          1:享元模式使得系统更加复杂。为了使对象可以共享,需要将一些状态外部化,这使得程序的逻辑复杂化。

          2:享元模式将享元对象的状态外部化,而读取外部状态使得运行时间稍微变长。

总结:

            享元模式一般是解决系统性能问题的,所以经常用于底层开发,在项目开发中并不常用。

 .NET的享元模式
         .NET中的String类型就是运用了享元模式。.NET中如果第一次创建了一个字符串对象s1,下次再创建相同的字符串s2时只是把它的引用指向s1所引用的具体对象,这就实现了相同字符串在内存中的共享。下面的程序来演示s1和s2的引

用是否一致: 输出的结果为True。

string s1 ="测试字符串一";
string s2 ="测试字符串一";
Console.WriteLine(Object.ReferenceEquals(s1, s2));

注意:如果再有一个字符串s3,它的初始值为“测试字符串”,再对它进行操作s3 = s3 + “一”,这时虽然s1和s3的值相同,但是它们的引用是不同的。

posted @ 2014-02-24 09:57  齐_大圣  阅读(301)  评论(0编辑  收藏  举报