1、Flyweight模式 一.意图运用共享技术有效地支持大量细粒度的对象。 二.适用性1、一个应用程序使用了大量的对象。2、完全由于使用大量的对象,造成特别大的存储开销。3、对象的大多数状态都可变为外部状态。4、要是删除对象的外部状态,那么能够用相对较少的共享对象取代许多组对象。5、应用程序不依靠于对象标识。由于Flyweight对象能够被共享,关于概念上明显有不的对象,标识测试将返回真值。 三.实例: 设计一个图书的治理系统,每本书都有出版社、编号、作者、价钞票等的属性,因此那个书的类能够如此设计: classBook { public: stringGetPublish(){
2、returnm_publishCompany;} stringGetWriter(){returnm_writer;} intGetBookID(){returnm_bookID;} intGetPrice(){returnm_price;} stringGetName(){returnm_name;} voidSetPublish(string&s){m_publishCompany=s;} voidSetWriter(string&s){m_writer=s;} voidSetBookID(intid){m_bookID=id;} voidSetPrice(intprice
3、){m_price=price;} voidSetName(string&s){m_name=s;} private: stringm_publishCompany;//出版社 stringm_writer;//作者 intm_bookID;//书籍编号 intm_price;//价钞票 stringm_name;//书名 }; 这特不自然。然而随着系统的开发和试运行,这种设计就表现出一些缺乏的地点了,例如一般图书会特不多,成千上万本,在这些书中可能会有相同的出版社或者相同的作者,那对每本书来讲就会重复了,也确实是根基白费了一些重复的空间。 要是每本书都消耗一些空间,那整个
4、软件系统所消耗的空间是不可想象的。因此,我们就要想方法来解决那个咨询题。 想象一下系统里面Book类的使用: 1、先瞧瞧不用共享模式: Bookbook1,book2,book3; book1.SetPublish("机械工业出版社"); book1.SetWriter("候捷"); book1.SetBookID(0000); book1.SetPrice(20); book1.SetName("C++好野"); book2.SetPublish("人民邮电出版社"); book2.SetWriter("候捷"); book2.SetBookID(0001); tPr
5、ice(30); book2.SetName("C++是好劲"); book3.SetPublish("机械工业出版社"); book3.SetWriter("一雨田"); book3.SetBookID(0002); book3.SetPrice(50); book3.SetName("C++无得顶,我是铁头功..."); 那个地点有两个“机械工业出版社〞和两个“候捷〞,重复了。要是使用共享模式的话,那个地点的白费就能够防止了。 不瞧那个地点只有两个,想象一下成千上万本书时的空间白费... 2、使用共享模式,把出版社和作者两个属性作为享元(Fly~~Weight) Pub
6、lishFlyweightFactorypff; WriterFlyweightFactorywff; Bookbook1,book2,book3; book1.SetPublish(pff.GetPublish("机械工业出版社")->GetName()); ter(wff.GetWriter("候捷")->GetName()); book1.SetBookID(0000); book1.SetPrice(20); book1.SetName("C++好野"); book2.SetPublish(pff.GetPublish("人民邮电出版社")->GetName());
7、book2.SetWriter(wff.GetWriter("候捷")->GetName()); book2.SetBookID(0001); book2.SetPrice(30); book2.SetName("C++是好劲"); blish("机械工业出版社")->GetName()); book3.SetWriter(wff.GetWriter("一雨田")->GetName()); book3.SetBookID(0002); book3.SetPrice(50); book3.SetName("C++无得顶,我是铁头功..."); 什么缘故使用了PublishFly
8、weightFactory和WriterFlyweightFactory之后就能够节约空间了呢?微妙就在于GetPublish和GetWriter的实现: PublishFlyweight*GetPublish(stringkey) { PublishFlyweight*p; mapPublish::iteratorit; it=mapPublish.find(key); //存在那个Writer if(it!=mapPublish.end()) p=it; else {//插进那个PublishFlyweight p=newPublishFlyweight(key);
9、
mapPublish[key]=p;
}
returnp;
}
GetWriter的实现大同小异,那个地点就不列出来了,请瞧具体代码里的实现。
下面是完整的代码,能够在一个CPP文件里编译使用:
#pragmawarning(disable:4786)
#include
10、n*m_writer;} intGetBookID(){returnm_bookID;} intGetPrice(){returnm_price;} stringGetName(){returnm_name;} voidSetPublish(string*s){m_publishCompany=s;} voidSetWriter(string*s){m_writer=s;} voidSetBookID(intid){m_bookID=id;} voidSetPrice(intprice){m_price=price;} voidSetName(string&s){m_name=
11、s;} private: string*m_publishCompany;//出版社 string*m_writer;//作者 intm_bookID;//书籍编号 intm_price;//价钞票 stringm_name;//书名 }; classPublishFlyweight { public: PublishFlyweight(strings) {m_name=s;} stringGetName() {returnm_name;} private: stringm_name; }; classPublishFlyweightFactory {
12、public:
PublishFlyweight*GetPublish(stringkey)
{
PublishFlyweight*p;
map 13、插进那个PublishFlyweight
p=newPublishFlyweight(key);
mapPublish[key]=p;
}
returnp;
}
private:
map 14、yweightFactory
{
public:
WriterFlyweight*GetWriter(stringkey)
{
WriterFlyweight*p;
map 15、dl;
}
else
{//插进那个PublishFlyweight
p=newWriterFlyweight(key);
mapWriter[key]=p;
}
returnp;
}
private:
map 16、 17、ID(0000);
book1.SetPrice(20);
book1.SetName(string("<






