软件模式之Flyweight模式.pdf
FlyweightFlyweight 模式模式一意图一意图运用共享技术有效地支持大量细粒度的对象。二二适用性适用性1、一个应用程序使用了大量的对象。2、完全由于使用大量的对象,造成特别大的存储开销。3、对象的大多数状态都可变为外部状态。4、要是删除对象的外部状态,那么能够用相对较少的共享对象取代许多组对象。5、应用程序不依靠于对象标识。由于 Flyweight对象能够被共享,关于概念上明显有不的对象,标识测试将返回真值。三实例:三实例:设计一个图书的治理系统,每本书都有出版社、编号、作者、价钞票等的属性,因此那个书的类能够如此设计:classBookclassBook public:public:stringGetPublish()returnm_publishCompany;stringGetPublish()returnm_publishCompany;stringGetWriter()returnm_writer;stringGetWriter()returnm_writer;intGetBookID()returnm_bookID;intGetBookID()returnm_bookID;intGetPrice()returnm_price;intGetPrice()returnm_price;stringGetName()returnm_name;stringGetName()returnm_name;voidSetPublish(string&s)m_publishCompany=s;voidSetPublish(string&s)m_publishCompany=s;voidSetWriter(string&s)m_writer=s;voidSetWriter(string&s)m_writer=s;voidSetBookID(intid)m_bookID=id;voidSetBookID(intid)m_bookID=id;voidSetPrice(intprice)m_price=price;voidSetPrice(intprice)m_price=price;voidSetName(string&s)m_name=s;voidSetName(string&s)m_name=s;private:private:stringm_publishCompany;/stringm_publishCompany;/出版社出版社stringm_writer;/stringm_writer;/作者作者intm_bookID;/intm_bookID;/书籍编号书籍编号intm_price;/intm_price;/价钞票价钞票stringm_name;/stringm_name;/书名书名;这特不自然。然而随着系统的开发和试运行,这种设计就表现出一些缺乏的地点了,例如一般图书会特不多,成千上万本,在这些书中可能会有相同的出版社或者相同的作者,那对每本书来讲就会重复了,也确实是根基白费了一些重复的空间。要是每本书都消耗一些空间,那整个软件系统所消耗的空间是不可想象的。因此,我们就要想方法来解决那个咨询题。想象一下系统里面 Book 类的使用:1、先瞧瞧不用共享模式:Bookbook1,book2,book3;Bookbook1,book2,book3;book1.SetPublish(book1.SetPublish(机械工业出版社机械工业出版社););book1.SetWriter(book1.SetWriter(候捷候捷););book1.SetBookID(0000);book1.SetBookID(0000);book1.SetPrice(20);book1.SetPrice(20);book1.SetName(C+book1.SetName(C+好野好野););book2.SetPublish(book2.SetPublish(人民邮电出版社人民邮电出版社););book2.SetWriter(book2.SetWriter(候捷候捷););book2.SetBookID(0001);book2.SetBookID(0001);tPrice(30);tPrice(30);book2.SetName(C+book2.SetName(C+是好劲是好劲););book3.SetPublish(book3.SetPublish(机械工业出版社机械工业出版社););book3.SetWriter(book3.SetWriter(一雨田一雨田););book3.SetBookID(0002);book3.SetBookID(0002);book3.SetPrice(50);book3.SetPrice(50);book3.SetName(C+book3.SetName(C+无得顶,我是铁头功无得顶,我是铁头功.);.);那个地点有两个“机械工业出版社和两个“候捷,重复了。要是使用共享模式的话,那个地点的白费就能够防止了。不瞧那个地点只有两个,想象一下成千上万本书时的空间白费.2、使用共享模式,把出版社和作者两个属性作为享元(FlyWeight)PublishFlyweightFactorypff;PublishFlyweightFactorypff;WriterFlyweightFactorywff;WriterFlyweightFactorywff;Bookbook1,book2,book3;Bookbook1,book2,book3;book1.SetPublish(pff.GetPublish(book1.SetPublish(pff.GetPublish(机械工业出版社机械工业出版社)-GetName();)-GetName();ter(wff.GetWriter(ter(wff.GetWriter(候捷候捷)-GetName();)-GetName();book1.SetBookID(0000);book1.SetBookID(0000);book1.SetPrice(20);book1.SetPrice(20);book1.SetName(C+book1.SetName(C+好野好野););book2.SetPublish(pff.GetPublish(book2.SetPublish(pff.GetPublish(人民邮电出版社人民邮电出版社)-GetName();)-GetName();book2.SetWriter(wff.GetWriter(book2.SetWriter(wff.GetWriter(候捷候捷)-GetName();)-GetName();book2.SetBookID(0001);book2.SetBookID(0001);book2.SetPrice(30);book2.SetPrice(30);book2.SetName(C+book2.SetName(C+是好劲是好劲););blish(blish(机械工业出版社机械工业出版社)-GetName();)-GetName();book3.SetWriter(wff.GetWriter(book3.SetWriter(wff.GetWriter(一雨田一雨田)-GetName();)-GetName();book3.SetBookID(0002);book3.SetBookID(0002);book3.SetPrice(50);book3.SetPrice(50);book3.SetName(C+book3.SetName(C+无得顶,我是铁头功无得顶,我是铁头功.);.);什么缘故使用了 PublishFlyweightFactory 和 WriterFlyweightFactory 之后就能够节约空间了呢?微妙就在于 GetPublish 和 GetWriter 的实现:PublishFlyweight*GetPublish(stringkey)PublishFlyweight*GetPublish(stringkey)PublishFlyweight*p;PublishFlyweight*p;mapPublish:iteratorit;mapPublish:iteratorit;it=mapPublish.find(key);it=mapPublish.find(key);/存在那个存在那个 WriterWriterif(it!=mapPublish.end()if(it!=mapPublish.end()p=it;p=it;elseelse/插进那个插进那个 PublishFlyweightPublishFlyweightp=newPublishFlyweight(key);p=newPublishFlyweight(key);mapPublishkey=p;mapPublishkey=p;returnp;returnp;GetWriter 的实现大同小异,那个地点就不列出来了,请瞧具体代码里的实现。下面是完整的代码,能够在一个 CPP 文件里编译使用:#pragma#pragmawarning(disable:4786)warning(disable:4786)#include#include#include#include#include#includeusingnamespacestd;usingnamespacestd;classBookclassBook public:public:stringstringGetPublish()return*m_publishCompany;GetPublish()return*m_publishCompany;stringstringGetWriter()return*m_writer;GetWriter()return*m_writer;intintGetBookID()returnm_bookID;GetBookID()returnm_bookID;intintGetPrice()returnm_price;GetPrice()returnm_price;stringstringGetName()returnm_name;GetName()returnm_name;voidvoidSetPublish(string*s)m_publishCompany=s;SetPublish(string*s)m_publishCompany=s;voidvoidSetWriter(string*s)m_writer=s;SetWriter(string*s)m_writer=s;voidvoidSetBookID(intid)m_bookID=id;SetBookID(intid)m_bookID=id;voidvoidSetPrice(intprice)m_price=price;SetPrice(intprice)m_price=price;voidvoidSetName(string&s)m_name=s;SetName(string&s)m_name=s;private:private:stringstring*m_publishCompany;/*m_publishCompany;/出版社出版社stringstring*m_writer;/*m_writer;/作者作者intintm_bookID;/m_bookID;/书籍编号书籍编号intintm_price;/m_price;/价钞票价钞票stringstringm_name;/m_name;/书名书名;classPublishFlyweightclassPublishFlyweight publicpublic:PublishFlyweight(strings)PublishFlyweight(strings)m_name=s;m_name=s;stringstringGetName()GetName()returnm_name;returnm_name;private:private:stringm_name;stringm_name;classclassPublishFlyweightFactoryPublishFlyweightFactory public:public:PublishFlyweight*GetPublish(stringkey)PublishFlyweight*GetPublish(stringkey)PublishFlyweight*p;PublishFlyweight*p;map:iteratorit;map:iteratorit;it=mapPublish.find(key);it=mapPublish.find(key);/存在那个出版社存在那个出版社if(it!=mapPublish.end()if(it!=mapPublish.end()p=(*it).second;p=(*it).second;coutcout差不多有那个出版社差不多有那个出版社:GetName():GetName()你节约了你节约了GetGetName().c_str()Name().c_str()字节的空间字节的空间endl;endl;elseelse/插进那个插进那个 PublishFlyweightPublishFlyweightp=newPublishFlyweight(key);p=newPublishFlyweight(key);mapPublishkey=p;mapPublishkey=p;returnp;returnp;private:private:mapmapPublish;mapmapPublish;classclassWriterFlyweightWriterFlyweight public:public:WriterFlyweight(strings)WriterFlyweight(strings)m_name=s;m_name=s;stringstringGetName()GetName()returnreturnm_name;m_name;private:private:stringstringm_name;m_name;classclassWriterFlyweightFactoryWriterFlyweightFactory public:public:WriterFlyweight*GetWriter(stringkey)WriterFlyweight*GetWriter(stringkey)WriterFlyweight*p;WriterFlyweight*p;map:iteratorit;map:iteratorit;it=mapWriter.find(key);it=mapWriter.find(key);/存在那个存在那个 WriterWriterif(it!=mapWriter.end()if(it!=mapWriter.end()p=(*it).second;p=(*it).second;coutcout差不多有那个作者名字差不多有那个作者名字:GetName():GetName()你节约了你节约了GGetName().c_str()etName().c_str()字节的空间字节的空间endl;endl;elseelse/插进那个插进那个 PublishFlyweightPublishFlyweightp=p=newnewWriterFlyweight(key);WriterFlyweight(key);mapWriterkey=p;mapWriterkey=p;returnreturnp;p;private:private:mapmapWriter;mapmapWriter;voidvoidShowBookInfo(Bookbook)ShowBookInfo(Bookbook)coutcout书名:书名:Name()endl;Name()endl;coutcout编号:编号:book.GetBookID()endl;book.GetBookID()endl;coutcout价钞票:价钞票:book.GetPrice()endl;book.GetPrice()endl;coutcout出版:出版:book.GetPublish()endl;book.GetPublish()endl;coutbook.GetWriter()endl;coutbook.GetWriter()endl;coutendl;coutGetName();)-GetName();book1.SetWriter(&(wff.GetWriter(book1.SetWriter(&(wff.GetWriter(候捷候捷)-GetName();)-GetName();book1.SetBookID(0000);book1.SetBookID(0000);book1.SetPrice(20);book1.SetPrice(20);book1.SetName(string(C+book1.SetName(string(););ShowBookInfo(book1);ShowBookInfo(book1);sh(sh(人民邮电出版社人民邮电出版社)-GetName();)-GetName();book2.SetWriter(&(wff.GetWriter(book2.SetWriter(&(wff.GetWriter(候捷候捷)-GetName();)-GetName();book2.SetBookID(0001);book2.SetBookID(0001);book2.SetPrice(30);book2.SetPrice(30);book2.SetName(string(C+book2.SetName(string(););ShowBookInfo(book2);ShowBookInfo(book2);booketPublish(&(pff.GetPublish(booketPublish(&(pff.GetPublish(机械工业出版社机械工业出版社)-GetName();)-GetName();book3.SetWriter(&(wff.GetWriter(book3.SetWriter(&(wff.GetWriter(一雨田一雨田)-GetName();)-GetName();book3.SetBookID(0002);book3.SetBookID(0002);book3.SetPrice(50);book3.SetPrice(50);book3.SetName(string(C+book3.SetName(string();.);ShowBookInfo(book3);ShowBookInfo(book3);