天天看點

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模式思想是“共享”,換句話說,同一個執行個體對象,會被多個地方使用,當要改變被共享的對象時,就會有多個地方産生影響。