大话设计模式之享元模式

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


 

//是所有具体享元类的超类或接口,通过这个接口,fliweight可以接收并作用于外部状态
abstractclass Flyweight
{
    //参数为代码的外部状态,子类可以根据外部状态发生变化
    public abstract void Operation(int extrinsicstate);
};
 
class ConcretFlyweight : Flyweight
{
    public override void Operation(int extrinsicstate)
    {
        Console.WriteLine("ConcretFlyweight :" +extrinsicstate);
    }
};
 
//这里是指不需要共享的Flyweight子类,因为Flyweight接口共享成为可能,但他不强制共享,用来解决不需要共享的对象的问题
class UnsharedConcretFlyweight :Flyweight
{
    public override void Operation(int extrinsicstate)
    {
        Console.WriteLine("UnsharedConcret Flyweight :" + extrinsicstate);
    }
};
 
//这是一个享元工厂,用来创建并管理Flyweight对象。主要用来确保合理的共享Flyweight,当用户请求一个Flyweight时,FlyweightFactory对象提供一个已创建的实例或者创建一个
class FlyweightFactory
{
    private Hashtable flyweights = new Hashtable();
 
    //我们也并非一定要在构造函数中就初始化几个对象
    public FlyweightFactory()
    {
        flyweights.Add("X", new ConcretFlyweight());
        flyweights.Add("Y", new ConcretFlyweight());
        flyweights.Add("Z", new ConcretFlyweight());
    }
 
    public Flyweight GetFlyweight(string key)
    {
        return((Flyweight)flyweights[key]);
    }
};
 
void main()
{
    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);
 
    UnsharedConcretFlyweight uf = new UnsharedConcretFlyweight();
    uf.Operation(--extrinsicstate);
}


 

 

在享元对象内部并且不会随环境改变而改变的共享部分,可以称为享元对象的内部状态,而随环境改变的、不可共享的状态就是外部状态

 

享元模式可以避免大量非常相似的开销。

在程序设计中,有时需要设计大量细粒度的类实例来表示数据,如果发现这些实例除了几个参数外基本上是相同的,有时就可以大幅度的减少需要实例化的类的数量。如果能把那些参数移到类实例的外面,在方法调用时将他们传递进来,就可以通过共享大幅度的减少单个实例的数目。

 

书上给出的例子是:

    几个建网站的需求,网站虽然不同,但内部实现却相似

 

 

//是网站类的外部状态 , 网站的客户账号
public class User
{
    private string name;
    public User(string name)
    {
        this.name = name;
    }
 
    public string Name
    {
        get{ return name; }
    }
};
 
//网站抽象类
abstractclass Website
{
    public abstract void Use(User user);
};
 
//具体网站类
class ConcretWebsite :Website
{
    private string name = "";
    public ConcretWebsite(string name)
    {
        this.name = name;
    }
 
    public override void Use(User user)
    {
        Console.WriteLine("网站分类: " + name + "用户:" + user.Name);
    }
};
 
//网站工厂
class WebsiteFactory
{
    private Hashtable fws = new Hashtable();
 
    //获得网站分类
    public Website GetWebsiteCategory(string key)
    {
        if (!fws.ContainsKey(key))
            fws.Add(key, new ConcretWebsite(key));
        return fws[key];
    }
};
 
void main()
{
    WebsiteFactory f = new WebsiteFactory();
 
    Website fx = f.GetWebsiteCategory("产品展示");
    fx.Use("xiaoming");
 
    Website fy = f.GetWebsiteCategory("博客");
    fx.Use("xiaohong");
 
    //..
}


 

如果一个程序使用了大量的对象,而大量的这些对象造成了很大的存储开销就应该考虑使用这种模式   

使用了享元模式,就有了共享对象,实例总数就大大减少

 

比如在.NET中,

    String A = “hello”;

    String B = “hello”;

    Console.WriteLine(Object.ReferenceEquals(A,B));

得到的返回值就是true,表明他们两个共享一个对象。这就是用到了享元模式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值