Flyweight 享元模式(结构型模式)

面向对象的代价

面向对象很好的解决了系统抽象性的问题,同时在大多数情况下也不会损及系统的性能。但是,在某些特殊应用中,由于对象的数量太大,采用面向对象会给系统带来难以承受的内存开销。比如图形应用中的图元等对象、字处理应用中的字符对象等。

动机(Motivation)

采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,而带来很高的运行代价——主要指内存需求方面的代价。

如何避免大量细粒度对象问题的同时,让外部客户程序仍然能够透明地使用面向对象方式进行操作?

意图(Intent)

运用共享技术有效地支持大量细粒度的对象——《设计模式》GoF

    class Font//(4+4+4)bytes+8bytes=20bytes (8bytes:4bytes垃圾回收控制位,4bytes虚表指针)
{
public string fontName;//4bytes 只是举例子,实际中应该用属性的
public int size;//4bytes
public Color color;//4bytes
        public Font(string fontName,int size,Color color)
        {
            this.fontName = fontName;
            this.size = size;
            this.color = color;
        }
}
/*
4:string fontName,字符串比较特殊,由于已经用了字符串池,就不考虑它在堆中的大小,这里只计算了它的指针大小。
4:int size
4:Color color
8:4bytes垃圾回收控制位+4bytes虚表指针
共20bytes
*/ class Charactor//(2+4+20+2)bytes+8bytes=36bytes
{
pubic char chr;//2bytes
pubic Font font;//20bytes
}
/*
2:char chr
4:Font font,指针占4bytes
20:Font font 堆中大小
2:32位系统的4bytes填充效应,char chr只占2bytes,补充了2bytes
8:4bytes垃圾回收控制位+4bytes虚表指针
共36bytes
*/ class System
{
public static void Main()
{ List<Charactor> list=new List<Charactor>();
for (int i = ; i < ; i++)
{
Charactor charactor=new Charactor();
list.Add(charactor);
}
//36bytes*100000=3600000bytes≈3600k≈3.6M
//如果是1千万个对象结果就是大约360M,这就太大了,要考虑享元模式。
}
}

当Charactor 对象个数非常多时,就考虑使用享元模式了。需要对Charactor 进行改造:

    class Charactor
{
public char chr;
private Font font;
private static Dictionary<string,Font> dicFont; public Font CFunt
{
get { return font; }
set
{
string key = value.fontName + value.size + value.color; if (dicFont.Keys.Contains(key))
{
this.font = dicFont[key];
}
else
{
dicFont.Add(key, value);
this.font = value;
}
}
}
}

这样当出现重复的字体的时候就不会占用多余的空间了。

            Charactor c1=new Charactor();
Font f1= new Font("宋体", , Color.Red);
c1.CFunt = f1; Charactor c2 = new Charactor();
Font f2 = new Font("宋体", , Color.Red);
c2.CFunt = f2;

f1和f2是不同对象,它们指向不同的内存地址,但是在给c1,和c2的CFont赋值时,由于用了Dictionary<string,Font>,对c2的CFont就没有分配新的内存空间。当对象非常多的时候,这样可以节省很多的空间。

.NET中字符串池就是运用了享元模式。

Flyweight模式的几个要点

  • 面向对象很好地解决了抽象性的问题,但是作为一个运行在机器中的程序实体,我们需要考虑对象的代价问题。Flyweight设计模式主要解决面向对象的代价问题,一般不触及面向对象的抽象性问题。
  • Flyweight采用对象共享的做法来降低系统中对象的个数,从而降低细粒度对象给系统带来的内存压力。在具体实现方面,要注意对象状态的处理。
  • 对象的数量太大从而导致对象内存开销加大——什么样的数量才算大?这需要我们仔细的根据具体应用情况进行评估,而不能凭空臆断。

设计模式11: Flyweight 享元模式(结构型模式)的更多相关文章

  1. Flyweight 享元(结构型)

    一:描述:(该模式实际应用较少) Flyweight 享元模式是对大量细粒度的元素进行共享和重用.减少对象的创建减轻内存: 注和单例模式不同的是:享元模式的各个对象佣有各自的行为并可实例化,单例模式的 ...

  2. 设计模式(11)--Flyweight(享元模式)--结构型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 2.模式特点: 享元模 ...

  3. 设计模式(十二): Flyweight享元模式 -- 结构型模式

    说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面 ...

  4. 面向对象设计模式之Flyweight享元模式(结构型)

    动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行代价——主要指内存需求方面的代价.如何在避免大量细粒度对象问题的同 时,让外部客户程序仍然能够透明地使用面向对象的 ...

  5. Flyweight享元模式(结构型模式)

    1.面向对象的缺点 虽然OOP能很好的解决系统抽象的问题,并且在大多数的情况下,也不会损失系统的性能.但是在某些特殊的业务下,由于对象的数量太多,采用面向对象会给系统带来难以承受的内存开销.示例代码如 ...

  6. 设计模式之flyweight享元模式

    运用共享技术支持大量细粒度对象的使用 Flyweight模式(享元) Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模 ...

  7. (转)Java经典设计模式(2):七大结构型模式(附实例和详解)

    原文出处: 小宝鸽 总体来说设计模式分为三大类:创建型模式.结构型模式和行为型模式. 博主的上一篇文章已经提到过创建型模式,此外该文章还有设计模式概况和设计模式的六大原则.设计模式的六大原则是设计模式 ...

  8. 设计模式06: Adapter 适配器模式(结构型模式)

    Adapter 适配器模式(结构型模式) 适配(转换)的概念无处不在:电源转接头.电源适配器.水管转接头... 动机(Motivation)在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象 ...

  9. 设计模式09: Decorator 装饰模式(结构型模式)

    Decorator 装饰模式(结构型模式) 子类复子类,子类何其多加入我们需要为游戏中开发一种坦克,除了不同型号的坦克外,我们还希望在不同场合中为其增加以下一种多种功能:比如红外线夜视功能,比如水路两 ...

  10. 代理模式/proxy模式/结构型模式

    代理模式proxy 定义 为其他对象提供一种代理,并以控制对这个对象的访问.最简单的理解,买东西都是要去商店的,不会去工厂. java实现三要素 proxy(代理)+subject(接口)+realS ...

随机推荐

  1. 洛谷3004 [USACO10DEC]宝箱Treasure Chest

    题目:https://www.luogu.org/problemnew/show/P3004 一眼看上去就是记忆化搜索的dp.像 一双木棋 一样. 结果忘了记忆化.T了5个点. 然后加上记忆化.MLE ...

  2. bzoj 4566 找相同字符 —— 广义后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4566 建出两个串的广义后缀自动机: 统计每个点在两个串中出现次数的子树和,其实就是在两个串中 ...

  3. php跨域问题

    http://www.cnblogs.com/xiezn/p/5651093.html

  4. shell 脚本基础知识详细介绍(二)

    SimonSu 博客 评论墙 读者墙 链接 关于 linux中的sh脚本语法 玩linux都知道sh脚本的方便,但如何编写sh脚本却是像我这样的新手和菜鸟的难题.能不能编写得出来是一回事,了不了解又是 ...

  5. maven环境配置详解,及maven项目的搭建及maven项目聚合

    首先:Maven 3.2.1:不同版本中仓库中文件是不一样的,Maven运行,先找用户配置,再找全局配置 1. Maven全局配置:全局统一的配置文件,在maven的安装目录中 2. Maven用户配 ...

  6. 在windows环境中使用varnish

    varnish 的windows 版本下载地址:   http://sourceforge.net/projects/cygvarnish/files/windows-zip-bundle/     ...

  7. Vue.js:安装

    ylbtech-Vue.js:安装 1.返回顶部 1. Vue.js 安装 1.独立版本 我们可以在 Vue.js 的官网上直接下载 vue.min.js 并用 <script> 标签引入 ...

  8. js作用域和作用域链

    作用域 首先要知道一点,js跟python都是一样的,先编译后执行 唯一的区别在于,js对于只声明,未定义的变量,报错是未定义,后面代码会有这个例子 编译的过程只有赋值和开辟空间的过程 只有函数,类才 ...

  9. Py修行路 python基础 (四)运算 copy

    字符串的格式化 在字符串中插入 %s ,作为占位符,后边儿再定义插入变量. 算术运算 % 取模   判断奇偶数 / 除法   有小于号 // 取整除  返回整数部分 逻辑运算 and or not ' ...

  10. 第五章 bean的加载(待续)

    ·············