设计模式-享元模式(十一)

享元模式:
  • 以共享的方式高效地支持大量细粒度对象
  • 有时在大并发大数量多循环的情况下new 了大量一样的对象会占据很多内存,从而导致内存溢出 OutOfMemory
  • 享元模式分内蕴状态(不可以改变的状态)和外蕴状态(必须客户端修改,并且不能改变内蕴状态),String类型就使用了享元模式,在JVM里面,每一个String都是唯一的.

享元模式其实就是用的缓存思想,创建太多的对象耗内存,如果这些对象可以分有限的类别,那我们就可以先把这些按此类别存储起来,下次要的时候就直接取就可以了.


注意线程安全问题
解决办法就是尽量创建足够多的对象....

  • 上类图


    享元模式.png

代码示例

  1. 定一个一个产品的抽象接口,在这个模式里面有没有都无所谓了,不过按套路来还是定一个高大上一点
package com.byedbl.flyweight;

/**
 *  A FlyWeight
 */
public interface Font  {
    void setFont(String color, int size);
    void getFont();
}
  1. 实现一个产品
package com.byedbl.flyweight;
/**
 *  A shared ConcreteFlyweight
 */
public class ConcreteFont implements Font {
    private String color;
    private int size;
    private String key;
    
    public ConcreteFont(String s) {
        key = s;
        //id = "The char is: " + s;
    }
    public void setFont(String _color, int _size) {
        color = _color;
        size = _size;
    }
    public void getFont() {
        System.out.println("String :" + key + "--- color is:" + color + "--- size is:" + size);
    }
}
  1. 创建享元工厂,和一般的工厂不同的是多了个HashMap去存储已经创建的产品
package com.byedbl.flyweight; /**
 *  A Flyweight Factory
 */
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class FontFactory  {
    private Map<String, Font> charHashTable = new ConcurrentHashMap<>();
    
    public FontFactory() {
    }

    public Font getFlyWeight(String s) {
        if(charHashTable.get(s) != null) {
            return (Font)charHashTable.get(s);
        } else {
            Font tmp = new ConcreteFont(s);
            charHashTable.put(s, tmp);
            return tmp;
        }
    }
    public Map<String, Font> getFactory() {
        return charHashTable;
    }
}
  1. 客户端调用
package com.byedbl.flyweight;
/**
 *  A test client
 */
import java.util.*;

public class Test  {
    public static void main(String[] args) {
        int[] size = {8, 9, 10, 11, 12};
        String[] color = {"FFFFFF", "000000", "FF00FF", "CCCCCC", "111111"};
        FontFactory myFontFactory = new FontFactory();
        String aString = "A test string";
        for(int i = 0; i < aString.length(); i++) {
            int j = 0;
            j = (int)Math.floor(Math.random()*5);
            //System.out.println("j is:" + j + "---" +aString.substring(i, i+1));
            myFontFactory.getFlyWeight(aString.substring(i, i+1)).setFont(color[j], size[j]);
        }

        Map<String, Font> map = myFontFactory.getFactory();
        System.out.println("Hash table size is:" + map.size());
        for(int i = 0; i < aString.length(); i++) {
            ((Font)map.get(aString.substring(i, i+1))).getFont();
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容