`
sjk2013
  • 浏览: 2184200 次
文章分类
社区版块
存档分类
最新评论

大话设计模式之享元模式

 
阅读更多

面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题。但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价。那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面向对象的方式进行操作?

享元模式:运用共享技术有效的支持大量细粒度的对象

结构图:



解释:

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

  • Flyweight:所有具体享元类的超类或接口,通过这个接口,Flyweight尅接受并作用于外部状态

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

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

代码实现:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace 享元模式
{
    class Program
    {
        static void Main(string[] args)
        {
            //代码外部状态
            int extrinsicstate = 22;

            FlyweightFactory f = new FlyweightFactory();

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

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

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

            Flyweight uf = new UnsharedConcreteFlyweight();

            uf.Operation(--extrinsicstate);

            Console.Read();


        }
    }

//Flyweight 类,它是所有具体享元类的超类或接口
    abstract class Flyweight
    {
        public abstract void Operation(int extrinsicstate);
    }

    //ConcreteFlyweight类,继承Flyweight超类或实现Flyweight接口,并为内部状态增加存储空间
    class ConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinstate)
        {
            Console.WriteLine("具体Flyweight:" + extrinstate);

        }

    }

    //UnsharedConcreteFlyweight类,代表那些不需要共享的Flyweight子类
    class UnsharedConcreteFlyweight : Flyweight
    {
        public override void Operation(int extrinsicstate)
        {
            Console.WriteLine("不共享的具体Flyweight:" + extrinsicstate);
        }
    }

    //FlyweightFactory类,是一个享元工厂,用来创建并管理Flyweight对象
    class FlyweightFactory
    {

        //使用Hashtable需要调用using System.Collections;
        private Hashtable flyweights = new Hashtable();

        public FlyweightFactory()
        {
            flyweights.Add("X", new ConcreteFlyweight());
            flyweights.Add("Y", new ConcreteFlyweight());
            flyweights.Add("Z", new ConcreteFlyweight());

        }

        public Flyweight GetFlyweight(string key)
        {
            return ((Flyweight)flyweights[key]);
        }

    }



}

例子:网站共享


结构图:



代码实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace 网站共享代码
{
    class Program
    {
        static void Main(string[] args)
        {
            WebSiteFactory f=new WebSiteFactory ();

            WebSite fx=f .GetWebSiteCategory ("产品展示");
            fx .Use (new User ("王会来"));

            WebSite fy=f.GetWebSiteCategory ("产品展示");
            fy .Use (new User ("陈金荣"));

            WebSite fz=f.GetWebSiteCategory ("产品展示");
            fz.Use (new User ("韩学敏"));

            WebSite fl=f.GetWebSiteCategory ("博客");
            fl .Use (new User ("李双喆"));

            WebSite fm=f .GetWebSiteCategory ("博客");
            fm.Use (new User ("周医青"));

            WebSite fn = f.GetWebSiteCategory("博客");
            fn.Use(new User("唐欢"));
       
            Console .WriteLine ("得到网站分类总数为{0}",f.GetWebSiteCount ());
            Console.Read();
            

        }
    }

    //用户类 ,用于网站的客户账号,是“网站”类的外部状态
    public class User
    {
        private string name;
        public User(string name)
        {
            this.name = name;

        }

        public string Name
        {
            get { return name; }
        }

    }

    //网站抽象类
    abstract class WebSite
    {
        public abstract void Use(User user);
    }

    //具体网站类

    class ConcreteWebSite : WebSite
    {
        private string name = "";
        public ConcreteWebSite(string name)
        {
            this.name = name;
        }
        public override void Use(User user)
        {
            Console.WriteLine("网站分类:" + name + "用户:" + user.Name);
        }

    }

    //网站工厂类
    
    class WebSiteFactory
    {
        private Hashtable flyweights=new Hashtable ();
        //获得网站分类
        public WebSite GetWebSiteCategory(string key)
        {
            if (!flyweights .ContainsKey (key ))
                flyweights .Add (key ,new ConcreteWebSite (key ));
            return ((WebSite )flyweights [key ]);
            
        }

        //获得网站分类总数
        public int GetWebSiteCount()
        {
            return flyweights .Count ;
        }

    }



}

运行结果:




享元模式的应用

  • 如果一个应用程序使用了大量的对象,而大量的这些对象造成了很大的存储开销时
  • 当对象的大多数状态可以外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代多组对象

享元模式的优点:

  • 实例总数少了
  • 共享的对象越多,存储节约也就越多,节约量随着共享状态的增多而增大




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics