flyweigth享元设计模式与委托总结
今天听了两场webcast讲座,收获颇多。第一场是讲享元设计模式,享元设计模式应该就是把一些实体放到一个公用的集合体中,其他实体只需添加对这个集合体的引用,达到重复利用实体的效果,这样可以大大减少实体的生成。
比如一个实体类是经常使用到的,而恰恰系统需要生成很多这样的实体类,这样系统开销就会很大,为了减少这种开销,我们需要享元模式,他抽出这个实体类中一成不变的元素,放入到一个对象池中,这样实体类就可以添加对这个实体类的引用,获取实体类的元素。
而怎样去生成实体类的元素呢,这里我们可以通过key,如果对象池含有key值元素,则直接取出,若没有则反射key获取元素类实体。
委托是一种引用类型,他可以实例化,可以承载多个方法,不需了解方法具体,只需知道方法是否符合代理契约,如果符合,委托即可承载方法。当然一个委托可以做为方法的参数,实现事件回调。
一个c#睡前的故事就是讲委托的,可以看看,里面把委托用的神乎其神了。
我做的一个享元实例:
一个cd类、Artist类、ArtistFactory类
cd类包含cd各部分信息有cd名称、cd歌手、cd数量。
artist类包含歌手名、歌手昵称、歌手出生日期。
代码如下:
cd类
using System;
using System.Collections.Generic;
using System.Text;
namespace flyweight
{
class cd
{
public cd(string name, string singer)
{
this._name = name;
this._singer = singer;
this._dt = DateTime.Now;
}
string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
DateTime _dt;
public DateTime Dt
{
get { return _dt; }
set { _dt = value; }
}
string _singer;
internal Artist Artist
{
get { return new ArticstFactory().GetArtist(_singer); }
set { }
}
}
}
using System.Collections.Generic;
using System.Text;
namespace flyweight
{
class cd
{
public cd(string name, string singer)
{
this._name = name;
this._singer = singer;
this._dt = DateTime.Now;
}
string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
DateTime _dt;
public DateTime Dt
{
get { return _dt; }
set { _dt = value; }
}
string _singer;
internal Artist Artist
{
get { return new ArticstFactory().GetArtist(_singer); }
set { }
}
}
}
artist类
using System;
using System.Collections.Generic;
using System.Text;
namespace flyweight
{
class Artist
{
string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
string _nickname;
public string Nickname
{
get { return _nickname; }
set { _nickname = value; }
}
int _cdnum;
public int Cdnum
{
get { return _cdnum; }
set { _cdnum = value; }
}
}
}
using System.Collections.Generic;
using System.Text;
namespace flyweight
{
class Artist
{
string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
string _nickname;
public string Nickname
{
get { return _nickname; }
set { _nickname = value; }
}
int _cdnum;
public int Cdnum
{
get { return _cdnum; }
set { _cdnum = value; }
}
}
}
artistfactory类:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace flyweight
{
class ArticstFactory
{
public static Hashtable Htname=new Hashtable();
public Artist GetArtist(string name)
{
if (ArticstFactory.Htname.ContainsKey(name))
{
return (Artist)ArticstFactory.Htname[name];
}
else
{
Artist at = new Artist();
//we could select data from database to instance the at ;
at.Name = name;//setname
at.Nickname = name;
at.Cdnum = 1;//first get the num of the artist's cdnum
//put the at instance into the hashtable
ArticstFactory.Htname[name] = at;
//return at instance
return at;
}
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace flyweight
{
class ArticstFactory
{
public static Hashtable Htname=new Hashtable();
public Artist GetArtist(string name)
{
if (ArticstFactory.Htname.ContainsKey(name))
{
return (Artist)ArticstFactory.Htname[name];
}
else
{
Artist at = new Artist();
//we could select data from database to instance the at ;
at.Name = name;//setname
at.Nickname = name;
at.Cdnum = 1;//first get the num of the artist's cdnum
//put the at instance into the hashtable
ArticstFactory.Htname[name] = at;
//return at instance
return at;
}
}
}
}
客户端调用代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace flyweight
{
class Program
{
static void Main(string[] args)
{
ArrayList al=new ArrayList(100);
for (int i = 0; i < 100; i++)
{
cd c = null;
if (i == 10)
{
c = new cd("world!", "haiyan");
}
else
{
c = new cd("hello", "yaoguobiao");
}
al.Add(c);
}
for (int j = 0; j < 100; j++)
{
Console.WriteLine(((cd)al[j]).Artist.Name);
}
System.Threading.Thread.Sleep(11000);
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Collections;
namespace flyweight
{
class Program
{
static void Main(string[] args)
{
ArrayList al=new ArrayList(100);
for (int i = 0; i < 100; i++)
{
cd c = null;
if (i == 10)
{
c = new cd("world!", "haiyan");
}
else
{
c = new cd("hello", "yaoguobiao");
}
al.Add(c);
}
for (int j = 0; j < 100; j++)
{
Console.WriteLine(((cd)al[j]).Artist.Name);
}
System.Threading.Thread.Sleep(11000);
}
}
}
一个享元demo就是这样子,关键点就是如何存取cd实例到hashtable里面。
而委托实例如下:
using System;
using System.Collections.Generic;
using System.Text;
namespace delegatesl
{
class events
{
public void printe(string p)
{
Console.WriteLine(p + "1-------");
}
public void printf(string p)
{
Console.WriteLine(p + "2----------");
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace delegatesl
{
public delegate void printweituo(string name);
class weituo
{
printweituo _pwt;
public void setweit(printweituo pt)
{
this._pwt = pt;
}
public void printpwt()
{
if (null != this._pwt)
{
this._pwt("haha,hello delegate");
}
}
}
}
//客户端代码
using System;
using System.Collections.Generic;
using System.Text;
namespace delegatesl
{
class Program
{
static void Main(string[] args)
{
printweituo ptw1 = new printweituo(new events().printe);
ptw1 += new printweituo(new events().printf);
ptw1("hah");
weituo wt = new weituo();
wt.setweit(ptw1);
wt.printpwt();
System.Threading.Thread.Sleep(11000);
}
}
}
using System.Collections.Generic;
using System.Text;
namespace delegatesl
{
class events
{
public void printe(string p)
{
Console.WriteLine(p + "1-------");
}
public void printf(string p)
{
Console.WriteLine(p + "2----------");
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace delegatesl
{
public delegate void printweituo(string name);
class weituo
{
printweituo _pwt;
public void setweit(printweituo pt)
{
this._pwt = pt;
}
public void printpwt()
{
if (null != this._pwt)
{
this._pwt("haha,hello delegate");
}
}
}
}
//客户端代码
using System;
using System.Collections.Generic;
using System.Text;
namespace delegatesl
{
class Program
{
static void Main(string[] args)
{
printweituo ptw1 = new printweituo(new events().printe);
ptw1 += new printweituo(new events().printf);
ptw1("hah");
weituo wt = new weituo();
wt.setweit(ptw1);
wt.printpwt();
System.Threading.Thread.Sleep(11000);
}
}
}