大话设计模式-享元模式

享元模式

运营共享技术有效地支持大量细粒度的对象。

享元模式的原理

享元模式可以避免大量非常相似类的开销。在程序设计中,有时需要生成大量细粒度的类的实例来表示数据。

如果能发现这些实例除了几个参数外基本都是相通的,有时就能够大幅地减少需要实例化的类的数量。

如果能把那些参数移到类的实例的外面,在方法调用时将他们传递进来,就可以通过共享大幅地减少单个实例的数目。

我的理解是原来一个对象的实例,它的字段和属性占用100KB,那么100个对象就是占用了100*100KB内存,现在把不变的提炼出来共享,比如字段和属性中由50KB是不变的,那100个对象就是占用了100*50KB(变的)+50KB(不变的)的内存。

占用内存=外部信息大小*外部信息实例数量+内部信息大小*内部信息实例数量

维护一个键值对,外部信息的某个字段作为键,内部信息实例作为值,这样就做到了共享内部信息。

 

享元模式的使用时机

如果一个应用程序使用了大量的对象,而大量的对象造成了很大的存储开销。

对象的大多数状态是外部状态,如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。

 


 

 

享元模式结构演示

用户

public class User
{
    public string Name { get; private set; }
    public User(string name) => Name = 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
{
    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() => flyweights.Count;
}

测试结果

//网站工厂
WebSiteFactory f = new WebSiteFactory();
//声明两个论坛
WebSite fx = f.GetWebSiteCategory("论坛");
fx.Use(new User("路人甲"));
WebSite fy = f.GetWebSiteCategory("论坛");
fy.Use(new User("路人乙"));
//声明两个博客
WebSite fi = f.GetWebSiteCategory("博客");
fi.Use(new User("路人A"));
WebSite fj = f.GetWebSiteCategory("博客");
fj.Use(new User("路人B"));
//打印网站种类数量
Console.WriteLine($"网站的种类数量为:{f.GetWebsiteCount()}");
//测试结果
网站分类:论坛 用户:路人甲
网站分类:论坛 用户:路人乙
网站分类:博客 用户:路人A
网站分类:博客 用户:路人B
网站的种类数量为:2

 

posted @ 2018-12-06 11:44  田错  阅读(254)  评论(0编辑  收藏  举报