zoukankan      html  css  js  c++  java
  • 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("
    ");
                }
                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

    ···

  • 相关阅读:
    VS2013 调试窗口一闪而过的解决方法
    什么是文件?
    局部变量和全局变量的区别
    一个简单java程序的要素
    运行一个简单的Java程序
    Javascript 构造函数原型继承机制
    函数式编程之一等公民的函数
    弹性布局flex-兼容问题
    TypeScript中的枚举类型
    依赖注入
  • 原文地址:https://www.cnblogs.com/dgwblog/p/9892547.html
Copyright © 2011-2022 走看看