In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
这篇文章将为大家详细讲解有关如何理解Flyweight模式,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。
[Flyweight模式]
官方描述:
意图
运用共享技术有效地支持大量细粒度的对象。
适用性
1、一个应用程序使用了大量的对象。
2、完全由于使用大量的对象,造成很大的存储开销。
3、对象的大多数状态都可变为外部状态。
4、如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
5、应用程序不依赖于对象标识。由于Flyweight 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
我的描述:
在开始设计类的时候,很自然的根据现实情况把某些属性作为类的一部分,例如设计一个图书的管理系统,每本书都有出版社、编号、作者、价钱等的属性,所以这个书的类可以这样设计:
class Book
{
public:
string GetPublish() {return m_publishCompany;}
string GetWriter() {return m_writer;}
int GetBookID() {return m_bookID;}
int GetPrice() {return m_price;}
string GetName() {return m_name;}
void SetPublish(string &s) {m_publishCompany = s;}
void SetWriter(string &s) {m_writer = s;}
void SetBookID(int id) {m_bookID = id;}
void SetPrice(int price) {m_price = price;}
void SetName(string &s) {m_name = s;}
private:
string m_publishCompany; // 出版社
string m_writer; // 作者
int m_bookID; // 书籍编号
int m_price; // 价钱
string m_name; // 书名
};
这非常自然。但是随着系统的开发和试运行,这种设计就表现出一些不足的地方了,例如一般图书会非常多,成千上万本,在这些书中可能会有相同的出版社或者相同的作者,那对每本书来说就会重复了,也就是浪费了一些重复的空间。
如果每本书都耗费一些空间,那整个软件系统所耗费的空间是不可想象的。所以,我们就要想办法来解决这个问题。
高明的面向对象设计者就想出了这个办法,把一些相同的属性(把它叫做"享元")提取出来,并用一个表来管理(池),这就是Flyweight模式的思想所在。好了,我们现在来看看示意图:
这里的ConcreteFlyweight就是需要共享的属性(享元),例如上面的出版社和作者,这里的UnsharedConcreteFlyweight就是
不用共享的属性(书籍编号和价钱)。
想象一下系统里面Book类的使用:
1、先看看不用共享模式:
Book book1, book2, book3;
book1.SetPublish("机械工业出版社");
book1.SetWriter("候捷");
book1.SetBookID(0000);
book1.SetPrice(20);
book1.SetName("C++好野");
book2.SetPublish("人民邮电出版社");
book2.SetWriter("候捷");
book2.SetBookID(0001);
book2.SetPrice(30);
book2.SetName("C++是好劲");
book3.SetPublish("机械工业出版社");
book3.SetWriter("一雨田");
book3.SetBookID(0002);
book3.SetPrice(50);
book3.SetName("C++无得顶,我是铁头功...");
这里有两个"机械工业出版社"和两个"候捷",重复了。如果使用共享模式的话,这里的浪费就可以避免了。
别看这里只有两个,想象一下成千上万本书时的空间浪费...
2、使用共享模式,把出版社和作者两个属性作为享元(Fly~~Weight)
PublishFlyweightFactory pff;
WriterFlyweightFactory wff;
Book book1, book2, book3;
book1.SetPublish(pff.GetPublish("机械工业出版社")->GetName());
book1.SetWriter(wff.GetWriter("候捷")->GetName());
book1.SetBookID(0000);
book1.SetPrice(20);
book1.SetName("C++好野");
book2.SetPublish(pff.GetPublish("人民邮电出版社")->GetName());
book2.SetWriter(wff.GetWriter("候捷")->GetName());
book2.SetBookID(0001);
book2.SetPrice(30);
book2.SetName("C++是好劲");
book3.SetPublish(pff.GetPublish("机械工业出版社")->GetName());
book3.SetWriter(wff.GetWriter("一雨田")->GetName());
book3.SetBookID(0002);
book3.SetPrice(50);
book3.SetName("C++无得顶,我是铁头功...");
为什么使用了PublishFlyweightFactory和WriterFlyweightFactory之后就可以节省空间了呢?
奥妙就在于GetPublish和GetWriter的实现:
PublishFlyweight* GetPublish(string key)
{
PublishFlyweight *p;
mapPublish::iterator it;
it = mapPublish.find(key);
// 存在这个Writer
if(it != mapPublish.end() )
p = it;
else
{// 插入这个PublishFlyweight
p = new PublishFlyweight(key);
mapPublish[key] = p;
}
return p;
}
GetWriter的实现大同小异,这里就不列出来了,请看详细代码里的实现。
下面是完整的代码,可以在一个CPP文件里编译使用,由于使用CSDN提供的插入代码功能会使得整段拷贝有点问题,所以这里还是直接给出代码,并标注颜色,方便大家的拷贝:
// Flyweight.cpp
#pragma warning(disable: 4786)
#include
#include
#include
using namespace std;
class Book
{
public:
string GetPublish() {return *m_publishCompany;}
string GetWriter() {return *m_writer;}
int GetBookID() {return m_bookID;}
int GetPrice() {return m_price;}
string GetName() {return m_name;}
void SetPublish(string *s) {m_publishCompany = s;}
void SetWriter(string *s) {m_writer = s;}
void SetBookID(int id) {m_bookID = id;}
void SetPrice(int price) {m_price = price;}
void SetName(string &s) {m_name = s;}
private:
string *m_publishCompany; // 出版社
string *m_writer; // 作者
int m_bookID; // 书籍编号
int m_price; // 价钱
string m_name; // 书名
};
class PublishFlyweight
{
public:
PublishFlyweight(string s)
{
m_name = s;
}
string GetName()
{
return m_name;
}
private:
string m_name;
};
class PublishFlyweightFactory
{
public:
PublishFlyweight* GetPublish(string key)
{
PublishFlyweight *p;
map::iterator it;
it = mapPublish.find(key);
// 存在这个出版社
if(it != mapPublish.end() )
{
// 这里可能有点难懂,请查阅STL的帮助文档
// 其实second就是指 map 的 PublishFlyweight*
p = (*it).second;
cout
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.