Design Pattern | Decorator Flyweight (플라이트 패턴)

Flyweight 패턴이란?

  • Flyweight라는 영어 단어는 “플라이급” 이라는 의미가 된다. 권투에서 가장 무게가 가벼운 계급을 나타낸다.
  • Flyweight 패턴의 무게는 메모리 사용량이다.
  • Flyweight 패턴은 인스턴스를 가능한 한 많이 공유하여 메모리 사용량을 줄이는 방법이다.
  • GoF의 디자인 패턴에서는 구조와 관련된 디자인 패턴으로 분류된다.

Flyweight 패턴 예제 프로그램

파일에서 큰 문자의 텍스트를 읽고 그것을 표시하는 프로그램이다.

Class Diagram
Flyweight Pattern Class Diagram

1. BigChar 클래스

큰 문자를 나타내는 클래스이다.

BigChar.java

package com.devkuma.designpattern.structural.flyweight;

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

public class BigChar {

    // 큰 문자를 나타내는 문자열 ('#', '.', '\n'열)
    private String fontData;

    public BigChar(char charName) {
        try {
            ClassLoader loader = BigChar.class.getClassLoader();
            String file = loader.getResource("flyweight/big" + charName + ".txt").getFile();
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String line;
            StringBuffer buf = new StringBuffer();
            while ((line = reader.readLine()) != null) {
                buf.append(line);
                buf.append("\n");
            }
            reader.close();
            this.fontData = buf.toString();
        } catch (IOException e) {
            this.fontData = charName + "?";
        }
    }

    // 큰 문자 표시을 표시한다.
    public void print() {
        System.out.print(fontData);
    }
}

2. BigCharFactory 클래스

BigChar의 인스턴스를 공유하면서 생성하는 클래스이다.

BigCharFactory.java

package com.devkuma.designpattern.structural.flyweight;

import java.util.HashMap;

public class BigCharFactory {

    // 이미 만든 BigChar 인스턴스 관리
    private HashMap pool = new HashMap();

    private static BigCharFactory singleton = new BigCharFactory();

    private BigCharFactory() {
    }

    // 하나뿐인 인스턴스를 반환한다.
    public static BigCharFactory getInstance() {
        return singleton;
    }

    // BigChar의 인스턴스 생성 (공유)
    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;
    }
}

3. BigString 클래스

BigChar를 모아서 만든 “큰 문자열"을 나타내는 클래스입니다.

BigString.java

package com.devkuma.designpattern.structural.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();
        }
    }
}

4. Main 클래스

메인 처리를 실행하는 클래스이다.

Main.java

package com.devkuma.designpattern.structural.flyweight;

public class Main {
    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Usage: java Main digits");
            System.out.println("Example: java Main 1234");
            System.exit(0);
        }
        BigString bs = new BigString(args[0]);
        bs.print();
    }
}

5. 데이터

아래 txt 파일을 참조한다.
/java-design-pattern-tutorial/src/resources/com/devkuma/designpattern/flyweight

6. 실행 결과

아래 결과값은 프로그램애 인자값으로 0329를 넣고 실행시킨 결과이다.

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

Flyweight 패턴의 장점

인스턴스를 공유하면 매번 new를 할 필요가 없어져서 메모리 사용량이 적다. 보다 일반적으로 말하면 인스턴스를 공유하면 인스턴스를 생성하는데 필요한 리소스의 양을 줄일 수 있다. 리소스는 컴퓨터의 리소스이며 메모리는 리소스 유형이다.
시간도 자원 유형이다. 인스턴스를 new를 할 때마다 일정 시간이 걸린다면 Flyweight 패턴을 사용하여 인스턴스를 공유하면 인스턴스를 new를 하는 수 만큼 줄일 수 있다. 이렇게 함으로써 프로그램 속도를 향상 시킬 수 있다.