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. 冒泡排序的JavaScript实现

    1. 普通冒泡 思想 假设有n个数,按从小到大排序: 进行n-1次外循环,每次外循环会排好当前处理的数中的最大数,即进行第一次外循环排好所有数中的最大数,进行第二次外循环排好所有数中的次大数....直 ...

  2. Linux下GCC和Makefile实例(从GCC的编译到Makefile的引入)

    一.确认已经装好了GCC和Make的软件包 可以使用whereis命令查看: 如果whereis  gcc和whereis  make命令有结果,说明安装了这两个软件,可以继续往下做. 二.使用GCC ...

  3. oracle 索引,组合索引

    1. 组合索引 id,code      组合 id,number  组合 2. 排序cost 使用 id ,cost=0 使用 id+code  cost=0 使用 id+number  cost= ...

  4. RAC 11gR2模拟OCR和Votedisk损坏恢复过程

    1)破坏前的ocr和votedisk信息检查 检查ocr自动备份 [root@rac1 ~]# ocrconfig -showbackup rac2 2013/10/13 09:45:30 /u01/ ...

  5. 分布式开发框架Pebble使用说明

    简介 Pebble定位为一个好用.可靠.高性能.易扩展的分布式开发框架,支持多种使用方式: 使用完整的pebble框架 独立使用各pebble子模块 在其他框架中嵌入pebble框架. Pebble具 ...

  6. java代码水仙花

    总结:分离出百位,十位,各位,我总是模模糊糊的,总是分不清取膜与除号的作用区别: “%”的意思是“取膜”,表示取得的是余数 “/”的意思是除,得到的是除数. package com.a; //求水仙花 ...

  7. php学习之if

    <html> <head> <title>xxx</title> <style> #tian{ color:blue; float:left ...

  8. Flask之部署

    5.3 部署 当我们执行下面的hello.py时,使用的flask自带的服务器,完成了web服务的启动.在生产环境中,flask自带的服务器,无法满足性能要求,我们这里采用Gunicorn做wsgi容 ...

  9. LibEvent代码阅读--多缓冲区和零拷贝技术

    http://blog.chinaunix.net/uid-20937170-id-4827550.html

  10. Objective-C 的 self 和 super 详解 (用简单程序说明问题)

    在 Objective-C 中的类实现中经常看到这两个关键字 "self" 和 "super",以以前 oop 语言的经验,拿 c++ 为例,self 相当于 ...