设计模式11: Flyweight 享元模式(结构型模式)
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 享元模式(结构型模式)的更多相关文章
- Flyweight 享元(结构型)
一:描述:(该模式实际应用较少) Flyweight 享元模式是对大量细粒度的元素进行共享和重用.减少对象的创建减轻内存: 注和单例模式不同的是:享元模式的各个对象佣有各自的行为并可实例化,单例模式的 ...
- 设计模式(11)--Flyweight(享元模式)--结构型
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.模式定义: 享元模式是对象的结构模式.享元模式以共享的方式高效地支持大量的细粒度对象. 2.模式特点: 享元模 ...
- 设计模式(十二): Flyweight享元模式 -- 结构型模式
说明: 相对于其它模式,Flyweight模式在PHP实现似乎没有太大的意义,因为PHP的生命周期就在一个请求,请求执行完了,php占用的资源都被释放.我们只是为了学习而简单做了介绍. 1. 概述 面 ...
- 面向对象设计模式之Flyweight享元模式(结构型)
动机:采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中,从而带来很高的运行代价——主要指内存需求方面的代价.如何在避免大量细粒度对象问题的同 时,让外部客户程序仍然能够透明地使用面向对象的 ...
- Flyweight享元模式(结构型模式)
1.面向对象的缺点 虽然OOP能很好的解决系统抽象的问题,并且在大多数的情况下,也不会损失系统的性能.但是在某些特殊的业务下,由于对象的数量太多,采用面向对象会给系统带来难以承受的内存开销.示例代码如 ...
- 设计模式之flyweight享元模式
运用共享技术支持大量细粒度对象的使用 Flyweight模式(享元) Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模 ...
- (转)Java经典设计模式(2):七大结构型模式(附实例和详解)
原文出处: 小宝鸽 总体来说设计模式分为三大类:创建型模式.结构型模式和行为型模式. 博主的上一篇文章已经提到过创建型模式,此外该文章还有设计模式概况和设计模式的六大原则.设计模式的六大原则是设计模式 ...
- 设计模式06: Adapter 适配器模式(结构型模式)
Adapter 适配器模式(结构型模式) 适配(转换)的概念无处不在:电源转接头.电源适配器.水管转接头... 动机(Motivation)在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象 ...
- 设计模式09: Decorator 装饰模式(结构型模式)
Decorator 装饰模式(结构型模式) 子类复子类,子类何其多加入我们需要为游戏中开发一种坦克,除了不同型号的坦克外,我们还希望在不同场合中为其增加以下一种多种功能:比如红外线夜视功能,比如水路两 ...
- 代理模式/proxy模式/结构型模式
代理模式proxy 定义 为其他对象提供一种代理,并以控制对这个对象的访问.最简单的理解,买东西都是要去商店的,不会去工厂. java实现三要素 proxy(代理)+subject(接口)+realS ...
随机推荐
- js生成1~100随机数
(function (min,max){ var range = max - min; var rand = Math.random(); var num = min + Math.round(ran ...
- IPv6与IPv4最主要的不同
IP第6个版本(IPv6),是互联网协议的新版本,设计为IP第4版本(IPv4,RFC-791)的继任.从IPv4升级到IPv6主要的改变有以下几类: 扩展地址容量 IPv6将IP地址的位址从32位提 ...
- (7)Stream简介
流的个人理解: 怎样获得流: 怎样处理流: 中间操作和终端操作介绍: 中间操作和终端操作的使用: 流的个人理解: Stream也就是流,他和IO流不一样,他是java8诞生的东西,我对他的理解就是一个 ...
- 使用阿里云服务器(OOS)实现图片上传
一: 页面 <%@ page language="java" contentType="text/html; charset=utf-8" pageEnc ...
- Java-Maven-Runoob:Maven环境配置
ylbtech-Java-Maven-Runoob:Maven环境配置 1.返回顶部 1. Maven 环境配置 Maven 是一个基于 Java 的工具,所以要做的第一件事情就是安装 JDK. 如果 ...
- python开发函数进阶:可迭代的&迭代器&生成器
一,可迭代的&可迭代对象 1.一个一个的取值就是可迭代的 iterable#str list tuple set dict#可迭代的 ——对应的标志 __iter__ 2.判断一个变量是不 ...
- Linux学习笔记 -- yum 使用
yum是什么 yum( Yellow dog Updater, Modified)是一个在Fedora和RedHat以及SUSE中的Shell前端软件包管理器. 她基于RPM包管理,能够从指定的服务器 ...
- jQuery UI Draggable + Sortable 结合使用
工作中需要将一个左边的设计好的控件,拖拽到右边的面板中,同时保持右边面板中的控件自由排序,这时候就需要及支持拖拽又支持排序的操作了, Demo截图:从左边控件拖到右边区域 代码段: <scrip ...
- ELK(Elasticsearch/Logstash/Kibana)安装时常见错误总结
问题一: [2016-11-06T16:27:21,712][WARN ][o.e.b.JNANatives ] unable to install syscall filter: Java.lang ...
- spark编译安装 spark 2.1.0 hadoop2.6.0-cdh5.7.0
1.准备: centos 6.5 jdk 1.7 Java SE安装包下载地址:http://www.oracle.com/technetwork/java/javase/downloads/java ...