天天看点

GOF设计模式——Flyweight模式

一、什么是Flyweight模式

        Flyweight,是轻量级的意思,Flyweight模式旨在使得类的创建、使用变得简便。如何实现呢?在一般的编程里面,想要使用一个对象,会通过new的方式创建,那么每一个地方需要使用该对象,就要new一次,在计算机内存中则需要每次都要分配内存空间出来,当使用new的次数增多时,内存空间也随着消耗加大。Flyweight模式则是通过尽量共享实例来避免内存的大量消耗。

二、Flyweight模式的原理

GOF设计模式——Flyweight模式

Flyweight类:是一些需要被共享的类;

FlyweightFactory类:负责生成Flyweight类的工厂类;

Client类:调用类。

三、Flyweight模式实例

        现在由一些由许多普通字符组合成为“大型字符”的类,它的实例就是重实例。示例中根据传递的数字,输出对应的文件内容。进行示例之前,要准备一些txt文件。

GOF设计模式——Flyweight模式

本示例的txt文件内容如下:

GOF设计模式——Flyweight模式
GOF设计模式——Flyweight模式
GOF设计模式——Flyweight模式

UML图:

GOF设计模式——Flyweight模式

1、BigChar类

package com.cjs.Flyweight;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class BigChar {
    private final String PATH = "E:\\IntelliJ Idea\\designMode\\src\\main\\resources\\";
    private char charName;
    private String fontdata;

    public BigChar(char charName) {
        this.charName = charName;

        try {
            BufferedReader reader = new BufferedReader(new FileReader(PATH+"big" + charName + ".txt"));
            String line;
            StringBuffer buffer = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
                buffer.append("\n");
            }
            reader.close();
            this.fontdata = buffer.toString();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void print() {
        System.out.println(fontdata);
    }
}
           

        BigChar类定义了三个属性,PATH定义了文件路径,charName表示将要传进来的字符,如‘1’,‘2’等等,fontdata用于存储文件内容,以及输出。构造方法的作用是:根据传进来的字符,找到对应的txt文件,然后逐行读取信息,将信息用StringBuffer对象保存,最后一次性保存在fontdata字符串中。

2、BigCharFactory类

package com.cjs.Flyweight;

import java.util.HashMap;

public class BigCharFactory {
    private HashMap pool = new HashMap();
    private static BigCharFactory singleton = new BigCharFactory();//使用静态实现单例模式

    private BigCharFactory() {

    }

    public static BigCharFactory getInstance() {
        return singleton;
    }

    public synchronized BigChar getBigChar(char charName) {
        BigChar bigChar = (BigChar) pool.get("" + charName);
        if (bigChar == null) {
            bigChar = new BigChar(charName);
            pool.put("" + charName, bigChar);
        }
        return bigChar;
    }
}
           

        因为BigCharFactory对象是共享的,只需要一个,所以使用了单例模式,另外,该工厂类主要用于生产BigChar对象,所以定义了getBigChar方法,该方法作用是,先根据字符到pool里面找,是否存在对应的对象,如果存在,直接返回、使用BigChar对象,如果不存在,创建一个新的BigChar对象,并放在pool里面。pool是一个HashMap类型属性,使用键值对来管理BigChar对象。

3、BigString类

package com.cjs.Flyweight;

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));
        }
    }

    public void print() {
        for (int i = 0; i < bigChars.length; i++) {
            bigChars[i].print();
        }
    }
}
           

        BigString作用是根据传入的字符串,将其拆分为单个字符,通过字符获取对应的BigChar实例对象,逐个输出。

4、Main类

package com.cjs.Flyweight;

public class Main {
    public static void main(String[] args) {
        BigString bigString = new BigString("12323");
        bigString.print();
    }
}
           

输出结果:

GOF设计模式——Flyweight模式

四、总结

        Flyweight模式核心在FlyweightFactory类的getFlyweight()方法的算法,什么时候创建新对象,如何创建。值得注意的是,Flyweight模式思想是“共享”,换句话说,同一个实例对象,会被多个地方使用,当要改变被共享的对象时,就会有多个地方产生影响。