设计模式:享元(FlyWeight)模式
设计模式:享元(FlyWeight)模式
一、前言
享元(FlyWeight)模式顾名思义,既是轻量级的,原因就是享元,共享元素,这里的元素指的是对象。如何共享对象,那就是在检测对象产生的时候,如果产生的是同一个对象,那么直接使用已经产生的,听起来很像是单例模式,其实享元模式的内部实现就是很类似与单例模式的懒汉模式。享元的好处就是,在某些场景下可以节省内存,从而使得程序的性能得到提升。
那么到底什么对象是可以共享的呢?!比如操作系统安装的时候就已经自动保存的图标、字体等等东西,这些东西是可以共享的,我们可以拿来直接使用,比如说word上面的字体,这些都是享元,因为不会发生改变,属于intrinsic(固有的,内在的,本质的),而有的对象是不能共享的,被称为extrinsic(外在的),本例之中自己使用TXT文档创建了几个字体,分别表示0,1,2...然后使用程序读取这些字体生成一个对象,这样的对象不能改变,因此可以用来共享。学过计算机高级结构的都知道,共享的内存一定要保证一致性,发生改变的时候也同步更新,而这里的享元从始至终都没有发生过改变,因此可以作为共享变量。

二、代码
文本文件:




BigChar类:(单个字符所表达的类)
package zyr.dp.flyweight; import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException; public class BigChar { private char charname;
private String frontData;
public BigChar(char charname){
this.charname=charname;
try {
BufferedReader br=new BufferedReader(new FileReader("big"+charname+".txt"));
StringBuffer sb=new StringBuffer();
String line;
while((line=br.readLine())!=null){
sb.append(line+"\n");
}
br.close();
frontData=sb.toString();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void print(){
System.out.println(frontData);
}
}
BigCharFactory 类:
package zyr.dp.flyweight;
import java.util.HashMap;
public class BigCharFactory {
private HashMap pool=new HashMap();
private static BigCharFactory bigCharFactory=new BigCharFactory();
private BigCharFactory(){
}
public static BigCharFactory getInstance(){
return bigCharFactory;
}
public synchronized BigChar getBigChar(char name){
BigChar bigchar=(BigChar)pool.get(""+name);
if(bigchar==null){
bigchar=new BigChar(name);
pool.put(""+name, bigchar);
}
return bigchar;
}
public BigChar getBigCharNotUsed(char name){
return new BigChar(name);
}
}
BigString类:
package zyr.dp.flyweight;
public class BigString {
private BigChar [] bigchars;
public BigString(String word,boolean isUsed){
if(isUsed == true){
bigchars=new BigChar[word.length()];
BigCharFactory bf=BigCharFactory.getInstance();
for(int i=0;i<word.length();i++){
bigchars[i]=bf.getBigChar(word.charAt(i));
}
}else{
bigchars=new BigChar[word.length()];
BigCharFactory bf=BigCharFactory.getInstance();
for(int i=0;i<word.length();i++){
bigchars[i]=bf.getBigCharNotUsed(word.charAt(i));
}
}
}
public void print(){
for(int i=0;i<bigchars.length;i++){
bigchars[i].print();
}
}
}
Main类:
package zyr.dp.flyweight;
public class Main {
public static void main(String[] args) {
String name="221100";
testMemory( name, false);
testMemory( name, true);
}
public static void testMemory(String name,boolean isUsed){
System.out.println("是否使用轻量级:"+isUsed);
BigString bs=new BigString(name,isUsed);
bs.print();
countMemory();
System.out.println("=================");
}
public static void countMemory(){
Runtime.getRuntime().gc();
System.out.println("已使用内存:"+(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()));
}
}
运行结果:
是否使用轻量级:false
---****------
-------*-----
--------*----
-----**------
----*--------
--*******---- ---****------
-------*-----
--------*----
-----**------
----*--------
--*******---- -----**-----
-----**-----
-----**-----
-----**-----
-----**-----
-----**----- -----**-----
-----**-----
-----**-----
-----**-----
-----**-----
-----**----- ----*****----
---*-----*---
--*-------*--
--*-------*--
---*-----*---
----*****---- ----*****----
---*-----*---
--*-------*--
--*-------*--
---*-----*---
----*****---- 已使用内存:879440
=================
是否使用轻量级:true
---****------
-------*-----
--------*----
-----**------
----*--------
--*******---- ---****------
-------*-----
--------*----
-----**------
----*--------
--*******---- -----**-----
-----**-----
-----**-----
-----**-----
-----**-----
-----**----- -----**-----
-----**-----
-----**-----
-----**-----
-----**-----
-----**----- ----*****----
---*-----*---
--*-------*--
--*-------*--
---*-----*---
----*****---- ----*****----
---*-----*---
--*-------*--
--*-------*--
---*-----*---
----*****---- 已使用内存:876928
=================
运行结果
三、总结
在我们的程序中,使用了单例模式,同时为了享元,我们使用了类似于单例模式中的懒汉模式,加入synchronized是为了防止多线程中出现误入,当然在本例中是没有多线程的,加不加锁无所谓。同时,我们对比了没有使用享元的例子,(对比之前先启动GC回收一次内存)可以发现所占用的内存空间,明显使用了享元的占用的内存小,而没有使用享元的占用的内存多。并且这里我们要注意垃圾回收机制,在工厂类中,使用了HashMap来将BigChar对象保存起来,这样就形成了一个DAC(有向无环图),只要pool变量不被释放,我们使用的共享单元是不会被释放的。这样就保证了BigChar对象数组不被释放,在使用享元模式的时候一定要特别注意这种情况,因为垃圾回收器(GC)在内存占用过多的时候被唤醒,然后清理那些被再被使用的内存,采用的方式就是DAC。
设计模式:享元(FlyWeight)模式的更多相关文章
- Java 实现享元(Flyweight)模式
/** * 字母 * @author stone * */ public class Letter { private String name; public Letter(String name) ...
- 十二、享元(Flyweight)模式--结构模式(Structural Pattern)
Flyweight在拳击比赛中指最轻量级,即"蝇量级",有些作者翻译为"羽量级".这里使用"享元 模式"更能反映模式的用意. 享元模式以共享 ...
- python 设计模式之享元(Flyweight)模式
#写在前面 这个设计模式理解起来很容易.百度百科上说的有点绕口. #享元模式的定义 运用共享技术来有効地支持大量细粒度对象的复用. 它通过共享已经存在的对橡大幅度减少需要创建的对象数量.避免大量相似类 ...
- 设计模式C++描述----12.享元(Flyweight)模式
一. 概述 在面向对象系统的设计何实现中,创建对象是最为常见的操作. 这里面就有一个问题:如果一个应用程序使用了太多的对象,就会造成很大的存储开销.特别是对于大量轻量级(细粒度)的对象,比如在文档编辑 ...
- 享元(FlyWeight)模式
享元模式(Flyweight Pattern)主要用于减少创建对象的数量,以减少内存占用和提高性能.这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式.享元模式尝试 ...
- 十一、结构模式之享元(Flyweight)模式
什么是享元模式 享元模式是对象的结构模式,是运用共享技术来有效的支持大量细粒度的对象.享元对象能做到共享的关键是区分内蕴状态和外蕴状态.一个内蕴状态是存储在享元对象内部,并且是不会随环境改变而有所不同 ...
- 8. 星际争霸之php设计模式--享元模式
题记==============================================================================本php设计模式专辑来源于博客(jymo ...
- C++设计模式——享元模式
本文版权归果冻说所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.如果这篇文章对你有帮助,你可以请我喝杯咖啡. » 本文链接:http:// ...
- 【设计模式】Java设计模式 - 享元模式
Java设计模式 - 享元模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 原创作品,更多关注我CSDN: 一个有梦有戏的人 准备将博客园.CSDN一起记录分享自己 ...
- java设计模式——享元模式
一. 定义与类型 定义:提供了减少对象数量从而改善应用所需的对象结构的方式,运用共享技术有效地支持大量细粒度的对象 类型:结构性 二. 使用场景 (1) 常常应用于系统底层的开发,以便解决系统的性能 ...
随机推荐
- CentOS6.4 安装sftp
1.打开命令终端窗口,按以下步骤操作.使用ssh -V 命令来查看openssh的版本,版本必须大于4.8p1,低于的这个版本需要升级. [root@ecs-3c46 ~]# ssh -v OpenS ...
- c#异步编程async await
可以代替协程了 但是需要.net4 版本 unity2017以上版本可以用了 再也可以不用蛋疼的没有返回值的协程了 //异步编程,和Task一起用 async void TestAsync(){ // ...
- 8.14_end
the first interview 事件委托(ul.li) jsonp原理实现 印象最深的项目 each的实现 ajax的实现 性能优化的方法 判断Function和Boolean 印象最深的项目 ...
- hadoop源码svn下载地址
1.apache开源框架
- html锚点(mao dian)--特殊的超链接
锚点(anchor):其实就是超链接的一种,一种特殊的超链接 普通的超链接,<a href="路径"></a> 是跳转到不同的页面 而锚点,<a hr ...
- 判断当前IE浏览器是否支持JS
1.server 2008 r2 64位中自带的IE默认不支持js,这样一些有JS的页面就是失效,所以如果要考虑这方面的系统,需要判断浏览器是否支持JS <div class="js- ...
- [转]Using MVC 6 And AngularJS 2 With .NET Core
本文转自:http://www.c-sharpcorner.com/article/using-mvc-6-and-angularjs-2-with-net-core/ CoreMVCAngular2 ...
- C#语言-03.逻辑控制语句
a. 逻辑控制语句: i. 条件语句:先对条件判断,然后根据判断结果执行不同的分支 . If 和 if-else:判断“布尔表达式的值”来决定执行那个代码块 a. 语法:if(布尔表达式){ b. 布 ...
- C#项目””是针对”.NETFramework,Version=v4.5.2”但此计算机没有,需要修改为v4.5.1.
每次下载别人的代码都会出现这样的问题,以为是没有安装.NETFramework,就下载安装了,但是每次安装都会出现已安装高版本的4.6(Win10自带),无需下次安装,但是每次VS中都会显示有问题,而 ...
- Vue指令(四)--v-model
1.v-model的使用场景 1.v-model的使用,用于表单控件的数据绑定 2.v-model与value共同使用,实现选项框的选中事件,两者相同时,选中 3.v-model 与v-bind:va ...