Fork me on Gitee

Flyweight模式

Flyweight ??

Flyweight是“轻量级”的意思,指的是拳击比赛中选手体重最轻的等级。顾名思义,该设计模式的作用是为了让对象变“轻”。

  • 简单概括:通过尽量共享实例来避免new出实例
    这里的共享不是任何对象都是共享的,在满足业务逻辑要求的情况下,将会重复利用的对象在对象的生命周期中保持替换不变,二不需要重新安排创造新的对象,创建新的对象既浪费时间又浪费内存空间。时间也是一种资源。使用new关键字生成实例会花费时间。通过Flyweight模式共享实例可以减少使用new关键字生成实例的次数。这样,就可以提高程序运行速度。

  • 两个点:
    即为应该共享的信息与不应该共享的信息
    1.intrinsic(应该共享)
    Intrinsic的意思是“本质的”“固有的”。换言之,它指的是不论实例在哪里、不论在什么情况下都不会改变的信息,或是不依赖于实例状态的信息。
    2.extrinsic(不应该共享)
    Extrinsic的意思是“外在的”“非本质的”。也就是说,它是当实例的位置、状况发生改变时会变化的信息,或是依赖于实例状态的信息。

  • 防止创建多个实例:
    getBigchar方法是synchronized方法。如果不使用synchronized修饰符,在进行多个线程的处理时候将会出现多个实例

理清职责

  • 实现功能:我们以文件形式保存了大型字符0~9,和“-”,的字体数据 通过代码读入内存并且显示出来

|名字======>>.说明
|Bigchar |表示“大型字符”的类
|BigcharFactory |表示生成和共用Bigchar类的实例的类
|Bigstring |表示多个Bigchar组成的“大型字符串”的类
|MainT |测试程序行为的类



................
................
................
................
..##########....
................
................
................

....######......
..##......##....
..##......##....
..##......##....
..##......##....
..##......##....
....######......
................

....######......
..##......##....
..##......##....
....########....
..........##....
..##......##....
....######......
................


UML

Code

  • BigChar
public class BigChar {

    // 字符名字
    private char charname;

    // 大型字符串对应的数据
    private String fontdata;

    public BigChar(char charname) {
        this.charname = charname;
        try {
            BufferedReader buf=new BufferedReader(new FileReader(
                    "Resources\\FlyWeight\\big"+charname+".txt"
            ));

            String line;
            StringBuffer buffer = new StringBuffer();
            while ((line=buf.readLine())!=null){
                buffer.append(line);
                buffer.append("\n");
            }
            buf.close();
            this.fontdata= buffer.toString();
        }catch (IOException e){
            e.printStackTrace();
            this.fontdata=charname+"?";
        }
    }

    // 显示字符
    public void print(){
        System.out.println(fontdata);
    }

}

  • BigcharFactory

public class BigcharFactory {

    // 管理已经生成的实例 实现共享 但要保证不被垃圾回收器回收
    private HashMap<String,BigChar> pool=new HashMap<>();

    private BigcharFactory(){};

    private static BigcharFactory singleton=new BigcharFactory();

    public static BigcharFactory getInstance(){
        return singleton;
    }

    // 生成实例
    public synchronized BigChar getBigChar(char charname){
        BigChar aChar = pool.get("" + charname);
        if (aChar == null) {
            aChar=new BigChar(charname);
            pool.put(""+charname,aChar);
        }
        return aChar;
    }
}


  • BigString2、BigString


public class BigString {

    private BigChar[] bigChars;

    /**
     * 根据入参字符串 构造大型字符串
     */
    public BigString(String string){
        bigChars=new BigChar[string.length()];

        // 实现共享实例
        BigcharFactory factory = BigcharFactory.getInstance();
        for (int i = 0; i < bigChars.length; i++) {
             bigChars[i] = factory.getBigChar(string.charAt(i));
        }
        
    }
    // show
    public void print(){
        for (int i = 0; i < bigChars.length; i++) {
            bigChars[i].print();
        }
    }
}

public class BigString2 {

    private BigChar[] bigChars;

    /**
     * @param string 转入的构造出参数
     * @param shared 是否创建共享对象
     */
    public BigString2(String string,boolean shared) {
        if(shared){
            ininShared(string);
        }else{
            initUnshared(string);
        }
    }

    /**
     * 根据入参字符串 构造大型字符串,不使用共享方式
     * @param string
     */
    public void initUnshared(String string) {
        bigChars=new BigChar[string.length()];
        for (int i = 0; i < bigChars.length; i++) {
            bigChars[i]=new BigChar(string.charAt(i));
        }
    }
    /**
     * 根据入参字符串 构造大型字符串,使用共享的方式
     */
    public void ininShared(String string){
        bigChars=new BigChar[string.length()];
        // 实现共享实例
        BigcharFactory factory = BigcharFactory.getInstance();
        for (int i = 0; i < bigChars.length; i++) {
             bigChars[i] = factory.getBigChar(string.charAt(i));
        }
    }
    // show
    public void print(){
        for (int i = 0; i < bigChars.length; i++) {
            bigChars[i].print();
        }
    }
}


  • MainT
public class MainT {

    private static BigString2[] bsarray = new BigString2[1000];

    public static void main(String[] args) {

        System.out.println("共享内存:   ");
        testAllocation(true);

        System.out.println("不共享内存:");
        testAllocation(false);
    }

    private static void testAllocation(boolean b) {
        for (int i = 0; i < bsarray.length; i++) {
            bsarray[i] = new BigString2("1212123", b);
        }
        showMemory();
    }

    private static void showMemory() {
        /**
         * 实现内存判断
         */
        Runtime.getRuntime().gc();
        long used = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
        System.out.println("使用内存= "+used);
    }
}


  • 运行结果:

···

共享内存:
使用内存= 749616
不共享内存:
使用内存= 3264096

···

posted @ 2018-11-01 21:10  ---dgw博客  阅读(114)  评论(0编辑  收藏  举报