享元模式——大大方方共享对象

  享元模式(Flyweight)定义:运用共享技术有效地支持大量细粒度的对象。
  享元模式的定义提出了两个要求,细粒度和共享对象。因为要求细粒度,所以不可避免地会使对象数量多且性质相近,此时我们就将这些对象的信息分为两个部分:内部状态和外部状态。

  享元对象的状态分类:

  • 内部状态:在享元对象内部且不会随着环境改变而改变的共享部分
  • 外部状态:随环境改变而改变的,不可共享的部分
  • (例如五子棋中,棋子的黑白两色是内部状态,棋子的方位坐标是外部状态)

  使用场景:

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

  优点:

  • 它通过共享已经存在的对象(相同对象只要保存一份),来大幅度减少需要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。

  缺点:

  • 需要维护一个记录了系统已有的所有的享元列表,这本身需要消耗资源。
  • 在没有足够多的对象实例可共享时,不要强制使用享元模式,因为为了使对象可以共享,需要将一些状态外部化,这样使得程序的逻辑复杂化。

在这里插入图片描述
  代码背景: 不同的网站之间差异其实不大,框架都是可共享的,仅仅是网站的功能不同,有的用来展示产品,有的用来发布新闻。

用户类:用于网站的客户账号,是网站类的外部状态

    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)//重写Use方法
        {
    
    
            Console.WriteLine("网站分类:" + name +" 用户:"+user.Name) ;
        }
    }

网站工厂类:

using System.Collections;//为了使用哈希表

    class WebSiteFactory
    {
    
    
        private Hashtable flyweights = new Hashtable();

        //获得网站分类
        public WebSite GetWebSiteCategory(string key)
        {
    
    
        	//判断键是不是不存在,这里if语句简写了
            if (!flyweights.ContainsKey(key))
                flyweights.Add(key,new ConcreteWebSite(key));//是不存在,就以键为name实例化一个ConcreteWebSite对象添加到哈希表
            return ((WebSite )flyweights[key]);//返回flyweights键为key的值,并把值强转成WebSite类型
        }
        //获得网站分类总数
        public int GetWebSiteCount()
        {
    
    
            return flyweights.Count;
        }
    }

客户端:

        static void Main(string[] args)
        {
    
    
            WebSiteFactory f = new WebSiteFactory();
            WebSite fx = f.GetWebSiteCategory ("产品展示");
            fx.Use(new User("咪西"));//实例用户对象,用于Use方法显示

            WebSite fy = f.GetWebSiteCategory("产品展示");
            fy.Use(new User("啾咪"));

            WebSite f1 = f.GetWebSiteCategory("博客");
            f1.Use(new User("旧浪"));

            WebSite f2 = f.GetWebSiteCategory("小游戏");
            f2.Use(new User("7k7k"));
			
			//实际网站只有三种
            Console.WriteLine("得到网站分类总数为{0}",f.GetWebSiteCount ());

        }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/CharmaineXia/article/details/111063511