一、定义
享元模式:运用共享技术有效地支持大量细粒度的对象。
解释:需要大量重复new一个对象时,使用享元模式可以让你减少对象的初始化,从而减小内存开销。太苍白了,理解的不到位,希望自己以后补充吧。
二、UML类图及基本代码
基本代码:
publicabstractclassFlyweight
{publicabstractvoidOperation(intextrinsicstate);
}publicclassConcreteFlyweight : Flyweight
{//内部状态PRivatestringintrinsicstate;//构造函数publicConcreteFlyweight(stringinnerState)
{this.intrinsicstate =innerState;
}///<summary>///享元类的实例方法///</summary>///<param name="extrinsicstate">外部状态</param>publicoverridevoidOperation(intextrinsicstate)
{
Console.WriteLine("具体实现类: intrinsicstate {0}, extrinsicstate {1}", intrinsicstate, extrinsicstate);
}
}publicclassFlyweightFactory
{//最好使用泛型Dictionary<string,Flyweighy>//public Dictionary<string, Flyweight> flyweights = new Dictionary<string, Flyweight>();publicHashtable flyweights =newHashtable();publicFlyweightFactory()
{
flyweights.Add("A",newConcreteFlyweight("A"));
flyweights.Add("B",newConcreteFlyweight("B"));
flyweights.Add("C",newConcreteFlyweight("C"));
}publicFlyweight GetFlyweight(stringkey)
{//更好的实现如下//Flyweight flyweight = flyweights[key] as Flyweight;//if (flyweight == null)//{//Console.WriteLine("驻留池中不存在字符串" + key);//flyweight = new ConcreteFlyweight(key);//}//return flyweight;returnflyweights[key]asFlyweight;
}
}
客户端调用:
classProgram
{staticvoidMain(string[] args)
{//定义外部状态,例如字母的位置等信息intexternalstate =10;//初始化享元工厂FlyweightFactory factory =newFlyweightFactory();//判断是否已经创建了字母A,如果已经创建就直接使用创建的对象AFlyweight fa = factory.GetFlyweight("A");if(fa !=null)
{//把外部状态作为享元对象的方法调用参数fa.Operation(--externalstate);
}//判断是否已经创建了字母BFlyweight fb = factory.GetFlyweight("B");if(fb !=null)
{
fb.Operation(--externalstate);
}//判断是否已经创建了字母DFlyweight fd = factory.GetFlyweight("D");if(fd !=null)
{
fd.Operation(--externalstate);
}else{
Console.WriteLine("驻留池中不存在字符串D");//这时候就需要创建一个对象并放入驻留池中ConcreteFlyweight d =newConcreteFlyweight("D");
factory.flyweights.Add("D", d);
}
Console.Read();
}
}
View Code
运行结果:
三、具体实例:
构建一个由不同用户使用的通用网站,具体代码如下:
publicclassUser
{privatestringname;publicstringName
{get{returnname; }
}publicUser(stringname)
{this.name =name;
}
}abstractclassWebsite
{publicabstractvoidUse(User user);
}classConcreteWebsite : Website
{privatestringname ="";publicConcreteWebsite(stringname)
{this.name =name;
}publicoverridevoidUse(User user)
{
Console.WriteLine("website type:"+ name +"user:"+user.Name);
}
}classWebsiteFactory
{privateHashtable flyweights =newHashtable();publicWebsite GetWebsiteCategory(stringkey)
{if(!flyweights.ContainsKey(key))
{
flyweights.Add(key,newConcreteWebsite(key));
}return((Website)flyweights[key]);
}publicintGetWebsiteCount()
{returnflyweights.Count;
}
}
客户端调用:
WebsiteFactory wf =newWebsiteFactory();
Website wx= wf.GetWebsiteCategory("show");
wx.Use(newUser("a"));
Website wy= wf.GetWebsiteCategory("show");
wy.Use(newUser("b"));
Website wz= wf.GetWebsiteCategory("see");
wz.Use(newUser("c"));
Console.WriteLine("website type num:"+ wf.GetWebsiteCount());
View Code
四、优缺点及适用场景
优点:
降低了系统中对象的数量,从而降低了系统中细粒度对象给内存带来的压力。
缺点:
1)为了使对象可以共享,需要将对象的一些状态外部化,增加了系统复杂度
2)将享元对象状态外部化,使得读取外部状态的运行时间稍微变长。
适用场景:
系统中需要大量的细粒度对象,同时这些对象耗费大量的内存,并且对象的状态大部分可以外部化,此时使用享元模式是没有错的。