Java用享元模式优化程序性能

来源:互联网 发布:ios11 蜂窝移动网络 编辑:程序博客网 时间:2024/06/04 18:51

为什么需要享元模式

  在有些项目中,要重复用到多个对象,此时,为了节省资源,可以让重复的对象只生成一次。
  例如,一个文档里面有30万个汉字,每个汉字都要显示出来,如果把每个汉字看成一个对象,要生成30万个对象,消耗内存。
  但是已经发现,30万个汉字有很多重复的,最后要使用的汉字大概几千字,那么,只需要实例化几千个对象,让它们放在一个池中,要用到的时候,就取出来,节省内存。此时可以使用享元(Flyweight)模式。
  注意
  1.享元模式是一种常见的软件设计模式,对象称为享元。在该模式中,运用了共享技术有效地支持大量细粒度的对象。系统只使用少量的对象,状态变化很小,对象使用次数增多。
  2.这里不详细介绍享元模式,只是介绍Java享元模式的一种实现,详细的定义等等可以自行搜索相关文档。

重要技术

  1.享元池如何实现
  享元池保存的是一个个享元,如果池中没有享元,则生成享元放到池中,如果有,则使用池中的享元。这里可以用使用Map,以享元关键字为key,享元对象为value,每个关键字和对象对应,保存在Map中。
  但是,不能盲目向Map中添加数据,当一个享元第一次出现时,Map中并没有这个对象,此时,需要进行判断。如果不存在,则将享元放入Map,否则将从Map中取出该享元。
  2.如何确定享元的关键字
  特征完全相同的对象可以认为是同一个享元。“特征相同”这是一个比较复杂的问题:例如,在控制台上打印,两个汉字,内容相同,就可以用同一个对象表达;但是如果保存到word文件中,内容相同,还不能用同一个对象表达,必须颜色、大小等一系列的特征相同。
  所以,享元的关键字必须能够表达一个享元的特征。
  ps:下面代码为了简单起见将汉字的内容作为关键字,也就是说两个汉字内容相同,就用同一个对象表达。

代码编写

首先是享元类Word.java

package practice;public class Word {    private String key;    public Word() {        System.out.println("实例化");    }    public void setKey(String key) {        this.key=key;    }    public void display() {        System.out.println(key+" 显示");    }}

接下来是享元池类:

package practice;import java.util.HashMap;public class FlyweightPool {    private static HashMap<String,Word> pool=new HashMap<>();    public static Word getFlyweight(String key) {        Word word=(Word)pool.get(key);        if(word==null) {            word=new Word();            word.setKey(key);            pool.put(key,word);        }        return word;    }}

最后是主函数所在模块,负责调用上面的两个模块:

package practice;public class Main {    public static void main(String[] args) {        Word word1=FlyweightPool.getFlyweight("中");        Word word2=FlyweightPool.getFlyweight("华");        Word word3=FlyweightPool.getFlyweight("中");        Word word4=FlyweightPool.getFlyweight("国");        word1.display();        word2.display();        word3.display();        word4.display();    }}

运行结果如下:
这里写图片描述
从中可以看出,实例化是三个对象而用了四次

注意

  当以下情况成立时可以考虑使用享元模式:
  1.一个应用程序使用了大量的对象。
  2.由于使用大量的对象,造成很大的存储开销。
  3.对象大多数状态都可变为外部状态(用关键字表达)。
享元模式可以大幅度地降低内存中对象的数量,但是,享元模式使得系统更加复杂。

原创粉丝点击