设计模式:享元(FlyWeight)模式

一、前言

    享元(FlyWeight)模式顾名思义,既是轻量级的,原因就是享元,共享元素,这里的元素指的是对象。如何共享对象,那就是在检测对象产生的时候,如果产生的是同一个对象,那么直接使用已经产生的,听起来很像是单例模式,其实享元模式的内部实现就是很类似与单例模式的懒汉模式。享元的好处就是,在某些场景下可以节省内存,从而使得程序的性能得到提升。

    那么到底什么对象是可以共享的呢?!比如操作系统安装的时候就已经自动保存的图标、字体等等东西,这些东西是可以共享的,我们可以拿来直接使用,比如说word上面的字体,这些都是享元,因为不会发生改变,属于intrinsic(固有的,内在的,本质的),而有的对象是不能共享的,被称为extrinsic(外在的),本例之中自己使用TXT文档创建了几个字体,分别表示0,1,2...然后使用程序读取这些字体生成一个对象,这样的对象不能改变,因此可以用来共享。学过计算机高级结构的都知道,共享的内存一定要保证一致性,发生改变的时候也同步更新,而这里的享元从始至终都没有发生过改变,因此可以作为共享变量。

二、代码

 文本文件:

 BigChar类:(单个字符所表达的类)

 1 package zyr.dp.flyweight;
 2
 3 import java.io.BufferedReader;
 4 import java.io.FileNotFoundException;
 5 import java.io.FileReader;
 6 import java.io.IOException;
 7
 8 public class BigChar {
 9
10     private char charname;
11     private String frontData;
12     public BigChar(char charname){
13         this.charname=charname;
14         try {
15             BufferedReader br=new BufferedReader(new FileReader("big"+charname+".txt"));
16             StringBuffer sb=new StringBuffer();
17             String line;
18             while((line=br.readLine())!=null){
19                 sb.append(line+"\n");
20             }
21             br.close();
22             frontData=sb.toString();
23         } catch (FileNotFoundException e) {
24             e.printStackTrace();
25         } catch (IOException e) {
26             // TODO Auto-generated catch block
27             e.printStackTrace();
28         }
29     }
30     public void print(){
31         System.out.println(frontData);
32     }
33 }

BigCharFactory 类:
 1 package zyr.dp.flyweight;
 2
 3 import java.util.HashMap;
 4
 5 public class BigCharFactory {
 6
 7     private HashMap pool=new HashMap();
 8
 9     private static BigCharFactory bigCharFactory=new BigCharFactory();
10
11     private BigCharFactory(){
12
13     }
14
15     public static BigCharFactory getInstance(){
16         return bigCharFactory;
17     }
18
19     public synchronized BigChar getBigChar(char name){
20         BigChar bigchar=(BigChar)pool.get(""+name);
21         if(bigchar==null){
22             bigchar=new BigChar(name);
23             pool.put(""+name, bigchar);
24         }
25         return bigchar;
26     }
27     public  BigChar getBigCharNotUsed(char name){
28         return new BigChar(name);
29     }
30
31 }

 BigString类:

 1 package zyr.dp.flyweight;
 2
 3 public class BigString {
 4
 5     private BigChar [] bigchars;
 6     public BigString(String word,boolean isUsed){
 7         if(isUsed == true){
 8             bigchars=new BigChar[word.length()];
 9             BigCharFactory bf=BigCharFactory.getInstance();
10             for(int i=0;i<word.length();i++){
11                 bigchars[i]=bf.getBigChar(word.charAt(i));
12             }
13         }else{
14             bigchars=new BigChar[word.length()];
15             BigCharFactory bf=BigCharFactory.getInstance();
16             for(int i=0;i<word.length();i++){
17                 bigchars[i]=bf.getBigCharNotUsed(word.charAt(i));
18             }
19         }
20     }
21
22     public void print(){
23         for(int i=0;i<bigchars.length;i++){
24             bigchars[i].print();
25         }
26     }
27 }

 Main类:

 1 package zyr.dp.flyweight;
 2
 3 public class Main {
 4
 5     public static void main(String[] args) {
 6         String name="221100";
 7         testMemory( name, false);
 8         testMemory( name, true);
 9     }
10     public static void testMemory(String name,boolean isUsed){
11         System.out.println("是否使用轻量级:"+isUsed);
12         BigString bs=new BigString(name,isUsed);
13         bs.print();
14         countMemory();
15         System.out.println("=================");
16     }
17     public static void countMemory(){
18         Runtime.getRuntime().gc();
19         System.out.println("已使用内存:"+(Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory()));
20     }
21 }

运行结果:

是否使用轻量级:false
---****------
-------*-----
--------*----
-----**------
----*--------
--*******-------****------
-------*-----
--------*----
-----**------
----*--------
--*******---------**-----
-----**-----
-----**-----
-----**-----
-----**-----
-----**----------**-----
-----**-----
-----**-----
-----**-----
-----**-----
-----**---------*****----
---*-----*---
--*-------*--
--*-------*--
---*-----*---
----*****--------*****----
---*-----*---
--*-------*--
--*-------*--
---*-----*---
----*****----已使用内存:879440
=================
是否使用轻量级:true
---****------
-------*-----
--------*----
-----**------
----*--------
--*******-------****------
-------*-----
--------*----
-----**------
----*--------
--*******---------**-----
-----**-----
-----**-----
-----**-----
-----**-----
-----**----------**-----
-----**-----
-----**-----
-----**-----
-----**-----
-----**---------*****----
---*-----*---
--*-------*--
--*-------*--
---*-----*---
----*****--------*****----
---*-----*---
--*-------*--
--*-------*--
---*-----*---
----*****----已使用内存:876928
=================

运行结果

三、总结

   在我们的程序中,使用了单例模式,同时为了享元,我们使用了类似于单例模式中的懒汉模式,加入synchronized是为了防止多线程中出现误入,当然在本例中是没有多线程的,加不加锁无所谓。同时,我们对比了没有使用享元的例子,(对比之前先启动GC回收一次内存)可以发现所占用的内存空间,明显使用了享元的占用的内存小,而没有使用享元的占用的内存多。并且这里我们要注意垃圾回收机制,在工厂类中,使用了HashMap来将BigChar对象保存起来,这样就形成了一个DAC(有向无环图),只要pool变量不被释放,我们使用的共享单元是不会被释放的。这样就保证了BigChar对象数组不被释放,在使用享元模式的时候一定要特别注意这种情况,因为垃圾回收器(GC)在内存占用过多的时候被唤醒,然后清理那些被再被使用的内存,采用的方式就是DAC。

  程序代码

转载于:https://www.cnblogs.com/zyrblog/p/9250726.html

设计模式:享元(FlyWeight)模式相关推荐

  1. 设计模式--享元(Flyweight)模式

    模式定义 运用共享技术有效地支持大量细粒度的对象 类图 应用场景 如果系统有大量类似的对象,可以使用享元模式 优点 如果系统有大量类似的对象,可以节省大量的内存及CPU资源 要点总结 要点总结 如果系 ...

  2. 设计模式学习笔记——享元(Flyweight)模式

    设计模式学习笔记--享元(Flyweight)模式 @(设计模式)[设计模式, 享元模式, flyweight] 设计模式学习笔记享元Flyweight模式 基本介绍 享元案例 类图 实现代码 Big ...

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

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

  4. 设计模式学习笔记--享元(Flyweight)模式

    写在模式学习之前 什么是设计模式:在我们进行程序设计时,逐渐形成了一些典型问题和问题的解决方案,这就是软件模式:每一个模式描述了一个在我们程序设计中经常发生的问题,以及该问题的解决方案:当我们碰到模式 ...

  5. python 享元模式_python 设计模式之享元(Flyweight)模式

    #写在前面 这个设计模式理解起来很容易.百度百科上说的有点绕口. #享元模式的定义 运用共享技术来有効地支持大量细粒度对象的复用. 它通过共享已经存在的对橡大幅度减少需要创建的对象数量.避免大量相似类 ...

  6. java 地图模式_Java设计模式之从[Dota地图]分析享元(Flyweight)模式

    在Dota游戏的地图中有几百棵树,现在假设这些树木无非是这两种:白杨.枫树,数量一共为400棵,那么,在装载这个地图场景的时候,我们是不是应该给这400课树一一建立对象呢?(如:MapItem tre ...

  7. 设计模式(11)——享元(Flyweight)模式

    什么是享元模式? 享元模式跟CACHE机制类似,它运用共享技术有效地支持大量细粒度的对象.Flyweight通过尽可能地与其他对象共享数据来减少对内存的使用. Flyweight的经典例子就是字符处理 ...

  8. Java设计模式之享元flyweight模式代码示例

  9. Unity设计模式——享元模式(附代码)

    Unity设计模式--享元模式(附源码) 享元Flyweight模式是什么 享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的 ...

  10. JAVA设计模式--享元模式

    目录 一.什么是享元模式 二.享元模式在Java中的典型应用 三.享元模式的结构 单纯享元模式 复合享元模式 四.享元模式应用举例 五.享元模式的适用性 六.享元模式的特点 七.总结 一.什么是享元模 ...

最新文章

  1. iOS获取已安装的app列表(私有库)+ 通过包名打开应用
  2. 【转】vi编辑器中如何复制粘贴文本
  3. java安全编码指南之:表达式规则
  4. 基于Spring Boot配置文件的日志记录示例样本
  5. 推荐一款配有强大数据管理和可视化ETL的BI工具
  6. Requests 入门
  7. linux和windows精简版,win7 64/86 超级精简版877MB -三蛋作品
  8. 【181202】VC 屏幕画笔程序源码源代码
  9. Django入门教程
  10. 08.15恒指/德指做单思路导图及晚盘前瞻
  11. Lotka-Volterra模型
  12. cad计算机中怎么用除号,CAD中特殊符号如何输入?超全教程,一看就懂!
  13. 超级简单的K线合成方法
  14. 790-C语言的数组元素下标为何从0开始?
  15. 5分钟学会Cron表达式
  16. python对律师的作用_法律行业python教程——利用python批量制作律师函
  17. Android基于Google Zxing实现二维码/条形码扫描、生成二维码/条形码
  18. 微信小程序定时器获取消息并在tabber按钮显示未读消息
  19. sessioncookie
  20. 全志AXP209电源管理芯片介绍

热门文章

  1. Visual Assist X 安装、使用 和 快捷键
  2. http、TCP/IP协议与socket之间的区别
  3. java 内存泄漏场景_Java内存泄露的例子
  4. php加载外部html,VUE页面加载外部HTML实例详解
  5. windows 默认使用python3_小白都能上手的Python3编程环境搭建 (Windows 10)
  6. java变量只声明未初始化是否可以直接使用?
  7. 接口有class类对象吗
  8. 使用%的符号问题(只与被除数有关)
  9. 002_Spring Data JPA CRUD
  10. 016_CSS选择器列表