《软件模式之Flyweight模式41942.docx》由会员分享,可在线阅读,更多相关《软件模式之Flyweight模式41942.docx(17页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、Flyweigght模式一意图运用用共享技术有有效地支持大大量细粒度的的对象。二适用性 1、一个应用用程序使用了了大量的对象象。 2、完全由于于使用大量的的对象,造成成很大的存储储开销。 3、对象的大大多数状态都都可变为外部部状态。 4、如果删除除对象的外部部状态,那么么可以用相对对较少的共享享对象取代很很多组对象。 5、应用程序序不依赖于对对象标识。由由于Flyweeight 对象可以被被共享,对于概念上明明显有别的对对象,标识测测试将返回真真值。三实例:设计一个图书的的管理系统,每每本书都有出出版社、编号号、作者、价价钱等的属性性,所以这个个书的类可以以这样设计:class BBookpu
2、blic: stringg GetPPublissh() returrn m_ppublisshComppany; stringg GetWWriterr() returrn m_wwriterr; int GeetBookkID() retturn mm_bookkID; int GeetPricce() retuurn m_price; stringg GetNName() returrn m_nname; void SSetPubblish(strinng &s) m_ppublisshComppany = s; void SSetWriiter(sstringg &s) m_wrrit
3、er = s; void SSetBoookID(iint idd) mm_bookkID = id; void SSetPriice(innt priice) m_priice = pricee; void SSetNamme(strring &s) m_name = s;privatee: stringg m_puublishhCompaany; / 出版社社 stringg m_wrriter; / 作者 int m_bookIID; / 书书籍编号 int m_pricee; / 价钱钱 stringg m_naame; / 书名; 这非常自然。但但是随着系统统的开发和试试运行,这种种
4、设计就表现现出一些不足足的地方了,例例如一般图书书会非常多,成成千上万本,在在这些书中可可能会有相同同的出版社或或者相同的作作者,那对每每本书来说就就会重复了,也也就是浪费了了一些重复的的空间。如果每本书都耗耗费一些空间间,那整个软软件系统所耗耗费的空间是是不可想象的的。所以,我我们就要想办办法来解决这这个问题。想象一下系统里里面Book类的使用: 1、先看看不不用共享模式式: Book bbook1, bookk2, boook3; book1.SetPuublishh(机械工业出出版社); book1.SetWrriter(候捷); book1.SetBoookID(0000); book
5、1.SetPrrice(220); book1.SetNaame(CC+好野); book2.SetPuublishh(人民邮电出出版社); book2.SetWrriter(候捷); book2.SetBoookID(0001); book2.SetPrrice(330); book2.SetNaame(CC+是好劲); book3.SetPuublishh(机械工业出出版社); book3.SetWrriter(一雨田); book3.SetBoookID(0002); book3.SetPrrice(550); book3.SetNaame(CC+无得顶,我我是铁头功.); 这里有两个“
6、机械工业出出版社”和两个“候捷”,重复了。如如果使用共享享模式的话,这这里的浪费就就可以避免了了。 别看这里只有有两个,想象象一下成千上上万本书时的的空间浪费.2、使用共享模模式,把出版版社和作者两两个属性作为为享元(FlyWeigght) PublisshFlywweighttFactoory pfff; WriterrFlyweeightFFactorry wfff; Book bbook1, bookk2, boook3; book1.SetPuublishh(pff.GetPuublishh(机械工工业出版社)-GeetNamee(); book1.SetWrriter(wff.GGe
7、tWriiter(候捷)-GetNaame(); book1.SetBoookID(0000); book1.SetPrrice(220); book1.SetNaame(CC+好野); book2.SetPuublishh(pff.GetPuublishh(人民邮邮电出版社)-GeetNamee(); book2.SetWrriter(wff.GGetWriiter(候捷)-GetNaame(); book2.SetBoookID(0001); book2.SetPrrice(330); book2.SetNaame(CC+是好劲劲); book3.SetPuublishh(pff.GetP
8、uublishh(机械工工业出版社)-GeetNamee(); book3.SetWrriter(wff.GGetWriiter(一雨田)-GetNName(); book3.SetBoookID(0002); book3.SetPrrice(550); book3.SetNaame(CC+无得顶顶,我是铁头头功.); 为什么使用了了PubliishFlyyweighhtFacttory和WriteerFlywweighttFactoory之后就就可以节省空空间了呢? 奥妙就在于GetPubblish和GetWrriter的实现: PublisshFlywweightt* GettPublii
9、sh(sttring key) PubliishFlyyweighht *p; mapPuublishh:iteeratorr it; it = mapPuublishh.findd(key); / 存在在这个Wriiter if(itt != mmapPubblish.end() ) p = it; else / 插插入这个PubliishFlyyweighht p = new PPublisshFlywweightt(key); mapPPublisshkeyy = pp; returrn p; GetWriiter的实现大同同小异,这里里就不列出来来了,请看详详细代码里的的实现。 下面是
10、完整的代代码,可以在在一个CPP文件里里编译使用:/ Flywweightt.cpp#pragmaa warnning(ddisablle: 47786)#includde #includde #includde using nnamesppace sstd;class BBookpublic: stringg GetPPublissh() returrn *m_publiishCommpany; stringg GetWWriterr() returrn *m_writeer; int GeetBookkID() retturn mm_bookkID; int GeetPricce() re
11、tuurn m_pricee; stringg GetNName() returrn m_nname; void SSetPubblish(strinng *s) m_ppublisshComppany = s; void SSetWriiter(sstringg *s) m_wrriter = s; void SSetBoookID(iint idd) mm_bookkID = id; void SSetPriice(innt priice) m_priice = pricee; void SSetNamme(strring &s) m_namme = ss; privatee: strin
12、gg *m_ppublisshComppany; / 出版社社 stringg *m_wwriterr; / 作者 int m_bookIID; / 书书籍编号 int m_pricee; / 价钱钱 stringg m_naame; / 书名;class PPublisshFlywweighttpublic: PublisshFlywweightt(striing s) m_naame = s; stringg GetNName() retuurn m_name; privatee: stringg m_naame;class PPublisshFlywweighttFactoorypubl
13、ic: PublisshFlywweightt* GettPubliish(sttring key) PubliishFlyyweighht *p; map:iteeratorr it; it = mapPuublishh.findd(key); / 存在在这个出版社社 if(itt != mmapPubblish.end() ) p = (*it).secoond; coutt 已经有这个个出版社: GeetNamee() 你节节省了 GettName().c_sstr() 字节的空间间 endl; else / 插插入这个PuublishhFlyweeight p = new PPubli
14、sshFlywweightt(key); mapPPublisshkeyy = pp; returrn p; privatee: map mmapPubblish;class WWriterrFlyweeightpublic: WriterrFlyweeight(strinng s) m_namme = ss; stringg GetNName() returrn m_nname; privatee: stringg m_naame;class WWriterrFlyweeightFFactorrypublic: WriterrFlyweeight* GetWWriterr(striing k
15、eey) WriteerFlywweightt *p; map:iterrator it; it = mapWrriter.find(key); / 存在在这个Wriiter if(itt != mmapWriiter.eend() ) p = (*it).secoond; coutt 已经有这个个作者名字: GGetNamme() 你你节省了 GeetNamee().c_str() 字节的空间间 endl; else / 插插入这个PuublishhFlyweeight p = new WrriterFFlyweiight(kkey); mapWWriterrkey = p; returrn
16、 p; privatee: map mmapWriiter; ;void ShhowBoookInfoo(Bookk bookk) cout 书名名: bookk.GetNName() eendl; cout 编号号: bookk.GetBBookIDD() endll; cout 价钱钱: bookk.GetPPrice() endl; cout 出版版: bookk.GetPPublissh() enddl; cout 作者者: bookk.GetWWriterr() endll; cout GetNName() ); book1.SetWrriter( &(wfff.GettWritee
17、r(候捷捷)-GGetNamme() ); book1.SetBoookID(0000); book1.SetPrrice(220); book1.SetNaame(sttring(); ShowBoookInffo(boook1); book2.SetPuublishh( &(ppff.GeetPubllish(人民邮电出出版社)-GetNName() ); book2.SetWrriter( &(wfff.GettWriteer(候捷捷)-GGetNamme() ); book2.SetBoookID(0001); book2.SetPrrice(330); book2.SetNaame(sttring(); ShowBoookInffo(boook2); book3.SetPuublishh( &(ppff.GeetPubllish(机械工业出出版社)-GetNName() ); book3.SetWrriter( &(wfff.GettWriteer(一雨雨田)-GetNaame() ); book3.SetBoookID(0002); book3.SetPrrice(550); book3.SetNaame(sttring(); ShowBoookInffo(boook3);
限制150内