参考资料


• 维基百科https://en.wikipedia.org/wiki/Flyweight_pattern

• 百度百科http://baike.baidu.com/link?url=RIhzC8-C6HUnAX6DqI5IfjawN3yhOckKvj8wWLL9zL4OAqK_I4xpi55aAjTpQdm7mKYZj7fKGW-I4-qXcNsj-q

Flyweight模式简介


GoF:Use sharing to support large numbers of fine-grained objects efficiently.

GoF:使用共享的方式来高效地支持大量细粒度对象的使用。

Wikipedia:In computer programming, flyweight is a software design pattern. A flyweight is an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory. Often some parts of the object state can be shared, and it is common practice to hold them in external data structures and pass them to the flyweight objects temporarily when they are used.

Wikipedia:在计算机编程中,享元是一种软件设计模式。一个享元是一个对象,该对象通过和其他相似对象共享尽可能多的数据来减少内存的使用。当对象的重复使用将导致令人无法接受的内存使用量时,享元模式是一种解决大量使用对象问题的方法。通常情况下,对象的部分状态是可以共享的,通常我们将这部分数据存储在外部的数据结构中,当需要使用时,再将它们临时性地传递给享元。

百度百科:享元模式(FlyWeight),运用共享技术有效的支持大量细粒度的对象。

Flyweight模式详解


• 设计意图

运用共享技术来有效地支持大量细粒度的对象使用。

• 结构图

• 结构说明

▶ Flyweight

抽象享元角色,为具体享元角色定义了接口,通过接口享元可以接收外部状态。

▶ ConcreteFlyweight

具体享元角色,实现抽象享元角色定义的接口。如果存在内部状态,则为内部状态提供存储空间。一个具体享元角色必须是可以共享的,它存储的任何状态都必须内蕴,这就是说状态必须与具体享元角色对象的上下文无关。

▶ UnsharedConcreteFlyweight

复合享元角色。实际情况中,并不是所有的享元子类型都需要被共享。抽象享元角色接口只是使共享行为可行,但并不强制要进行共享。这种情况十分常见:在某些享元对象结构层次中,复合享元对象将具体享元对象作为孩子。

▶ FlyweightFactory

享元工厂角色,创建并管理享元对象实体。享元工厂将确保享元能够被正确地共享。当客户端请求一个享元,享元工厂对象将提供一个已有的享元实例,如果不存在,则创建一个新的享元实体。

▶ Client

客户端角色。维护享元对象的引用,计算或存储享元对象的外部状态。

• 享元共享示意图

Facade模式举例


• 例子一

这个例子出自于Wikipedia:https://en.wikipedia.org/wiki/Flyweight_pattern

#include <map>
#include <list>
#include <string>
#include <sstream>
#include <iomanip>
#include <iostream>
using namespace std; // Instances of CoffeeFlavour will be the Flyweights.
class CoffeeFlavour
{
private:
string m_strFlavourName; public:
CoffeeFlavour(const string &strFlavourName = "Unknown") : m_strFlavourName(strFlavourName) {} public:
const char *GetFlavourName() const
{
return m_strFlavourName.c_str();
}
}; typedef const CoffeeFlavour * const CPCCoffeeFlavour; // Menu acts as a FlyweightFactory and cache for CoffeeFlavour Flyweight objects
class Menu
{
typedef map<string, CPCCoffeeFlavour> FlavoursMap;
typedef map<string, CPCCoffeeFlavour>::iterator FlavoursMapIterator; public:
~Menu()
{
FlavoursMapIterator it = m_FlavoursMap.begin();
for (; m_FlavoursMap.end() != it; it++)
{
CPCCoffeeFlavour cpcCoffeeFlavour = it->second;
if (cpcCoffeeFlavour)
{
delete cpcCoffeeFlavour;
}
}
m_FlavoursMap.clear();
} private:
FlavoursMap m_FlavoursMap; public:
CPCCoffeeFlavour LookUp(const string &strFlavourName)
{
FlavoursMapIterator it = m_FlavoursMap.find(strFlavourName);
if (m_FlavoursMap.end() == it)
{
m_FlavoursMap.insert( pair<string, CPCCoffeeFlavour>(strFlavourName, ::new CoffeeFlavour(strFlavourName)) );
} return m_FlavoursMap[strFlavourName];
} int GetCoffeeFlavourCount()
{
return m_FlavoursMap.size();
}
}; class Order
{
private:
int m_nTableNumber;
CPCCoffeeFlavour m_cpcCoffeeFlavour; public:
Order(int nTableNumber, CPCCoffeeFlavour cpcCoffeeFlavour) :
m_nTableNumber(nTableNumber), m_cpcCoffeeFlavour(cpcCoffeeFlavour) {} public:
void Serve()
{
cout << left;
cout << "Serving "
<< setw() << m_cpcCoffeeFlavour->GetFlavourName()
<< " to table "
<< setw() << m_nTableNumber << endl;
}
}; class CoffeeShop
{
private:
Menu m_CoffeeMenu;
list<Order> m_CoffeeOrders; public:
void TakeOrder(const string &strFlavourName, int nTableNumber)
{
CPCCoffeeFlavour cpcFlavour = m_CoffeeMenu.LookUp(strFlavourName);
m_CoffeeOrders.push_back(Order(nTableNumber, cpcFlavour));
} void Service()
{
list<Order>::iterator it = m_CoffeeOrders.begin();
for (; m_CoffeeOrders.end() != it; it++)
{
it->Serve();
}
} string Report()
{
stringstream ss;
ss << "Total CoffeeFlavour Objects Made: " << m_CoffeeMenu.GetCoffeeFlavourCount();
return ss.str();
}
}; int main()
{
CoffeeShop shop; shop.TakeOrder("Cappuccino", );
shop.TakeOrder("Frappe", );
shop.TakeOrder("Espresso", );
shop.TakeOrder("Frappe", );
shop.TakeOrder("Cappuccino", );
shop.TakeOrder("Frappe", );
shop.TakeOrder("Espresso", );
shop.TakeOrder("Cappuccino", );
shop.TakeOrder("Espresso", );
shop.TakeOrder("Frappe", );
shop.TakeOrder("Cappuccino", );
shop.TakeOrder("Espresso", ); shop.Service();
cout << shop.Report() << endl; return ;
}

CoffeeFlavour作为享元共享结构图如下:

flyweight模式的更多相关文章

  1. 常见设计模式解析和实现(C++)FlyWeight模式

    作用:运用共享技术有效地支持大量细粒度的对象 UML结构图: 解析: Flyweight模式在大量使用一些可以被共享的对象的时候使用.比如,在QQ聊天时很多时候你懒得回复又不得不回复,一般会用一些客套 ...

  2. Flyweight 模式

    如果一个应用程序使用了太多的对象, 就会造成很大的存储开销. 特别是对于大量轻量级 (细粒度)的对象,比如在文档编辑器的设计过程中,我们如果为每个字母创建一个对象的话,系统可能会因为大量的对象而造成存 ...

  3. Structual设计--Flyweight模式

    1.意图 运用共享技术有效地支持大量细粒度的对象. 2.别名 无 3.动机 有些应用程序得意于在其整个设计过程中採用对象技术,但简单化的实现代价极大.如我们在使用word的时候.假设设置正文字体为:t ...

  4. Java 实现享元(Flyweight)模式

    /** * 字母 * @author stone * */ public class Letter { private String name; public Letter(String name) ...

  5. Flyweight模式_Java中23种设计模式

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流! —————————— 享元模式: Flyweight模式的有效性很大程度上取决于如何使用它以及在何处使用 ...

  6. Java设计模式(5)共享模式/享元模式(Flyweight模式)

    Flyweight定义:避免大量拥有相同内容的小类的开销(如耗费内存),使大家共享一个类(元类). 为什么使用共享模式/享元模式 面向对象语言的原则就是一切都是对象,但是如果真正使用起来,有时对象数可 ...

  7. 设计模式之——flyweight模式

    flyweight模式,又叫做享元模式. 顾名思义,享元模式就是共享一个元素. 百度百科 解释为: 享元模式(英语:Flyweight Pattern)是一种软件设计模式.它使用共享物件,用来尽可能减 ...

  8. Flyweight模式(亨元模式)

    这应该算是最好理解的一个设计模式了吧·················· 面向对象语言的原则就是一切都是对象,但是如果真正使用起来,有时对象数可能显得很庞大,比如,字处理软件,如果以每个文字都作为一个 ...

  9. 设计模式(二十)Flyweight模式

    当使用new关键字生成类的实例时,需要给其分配足够的内存空间.当程序中需要大量对象时,如果都是用new关键字来分配内存,将会消耗大量内存空间.Flyweight模式就是尽量避免new出实例,而是通过尽 ...

随机推荐

  1. 文件 I/O 问题

    文件 I/O 问题:(1)对不存在的或者错误的文件进行操作吗?(2)文件以不正确的方式打开吗?(3)文件结束判断不正确吗?(4)没有正确地关闭文件吗? #include <iostream> ...

  2. java---堆、栈、常量池的存储数据

    说到Java中堆.栈和常量池,首先还是看看他们各自存放的数据类型吧! 栈: Java的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method)也叫静态存储区. 堆区:(存放所 ...

  3. hdu 2234(IDA*)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2234 思路:IDA*可以搞,借鉴的是大牛的启发式函数h(): 可以考虑把每一行上的数转化成相同的,或者 ...

  4. redhat6.4 zabbix3.0.2安装

    zabbix不用说了,很好的服务器监控管理工具,还支持中文哈! 1.添加epel仓库,有更多可用的软件包 rpm -ivh http://download.fedoraproject.org/pub/ ...

  5. python 发送email

    pyton smtplib发送邮件 在邮件中设置并获取到 smtp域名 在脚本中执行命名,收件人可以是 多个,在列表中 import smtplib from email.mime.text impo ...

  6. 学习《深入理解C#》—— 数据类型、排序和过滤 (第一章1.1---1.2)

    引言 在开始看这本书之前看过一些技术博客,填补自己对于一些知识点的不足.无意中发现了<深入理解C#>这本书,本书主要探讨C# 2.C# 3和C# 4的细节与特性,所以做了一下阅读笔记,欢迎 ...

  7. HDU 2159 FATE(二维全然背包)

    中文题目就不用解释了   就是裸的二维全然背包 d[i][j]表示消耗i忍耐杀j个怪最多可获得的经验  然后就用全然背包来做了  二维背包背包只是是多了一重循环 <span style=&quo ...

  8. String、StringBuffer与StringBuilder区别

    1.三者在执行速度方面的比较:StringBuilder >  StringBuffer  >  String 2.String <(StringBuffer,StringBuild ...

  9. pushViewController自定义动画http://blog.csdn.net/ralbatr/article/details/22039233

     本文转载至  http://blog.csdn.net/ralbatr/article/details/22039233 实现的主要代码如下: CATransition *transition =  ...

  10. Zabbix-3.0.3结合Grafana-3.1.0给你想要的绘图

    导读 Grafana 是 Graphite 和 InfluxDB 仪表盘和图形编辑器.Grafana 是开源的,功能齐全的度量仪表盘和图形编辑器,支持 Graphite,InfluxDB 和 Open ...