본문 바로가기
개발/디자인 패턴

[Java 언어로 배우는 디자인 패턴 입문] 낭비 없애기 20. Flyweight

by hongdor 2021. 1. 17.
728x90

출처 : 책 - java 언어로 배우는 디자인 패턴 입문

 

20. Flyweight - 동일한 것을 공유해서 낭비 없애기

 

 

1. 목적

 

 - 객체를 가볍기 하기 위한 것. 가볍다는 것은 적은 메모리를 사용하는 것을 의미한다.

 - 인스턴스를 가능한 대로 공유시켜서 쓸데없이 new로 인스턴스 생성을 하지 않는다.

 - 주의할점 

   1. 공유되는 정보를 수정하면 전체에 영향을 미친다.

   2. 어떤 정보를 공유하게 할것이고, 어떤정보를 각자 클래스에 나눌것인지 판단해야 한다.

    Ex) 색상 속성을 공유하는 곳에 같이 설정할 수도 있고, 개별 클래스에 따로 속성값을 넣게 만들어줄 수도 있다.

   3. 사용하지 않아도 공유되어 참조되고 있으므로 garbage collection이 인스턴스를 삭제하지 않는다.

    > 인스턴스에 null을 참조하게 하여 참조를 제거해주는 방법이 있다. 

   4. 인스턴스 생성을 덜 하는만큼 프로그램의 속도가 향상된다.  

 

 

2. 예제

 

(1) BigChar - txt 파일을 불러오는 클래스.

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

public class BigChar {
    // 문자의 이름
    private char charname;
    // 큰 문자를 표현하는 문자열 ('#' '.' '\n'의 열)
    private String fontdata;
    // 생성자
    public BigChar(char charname) {
        this.charname = charname;
        try {
            BufferedReader reader = new BufferedReader(
                new FileReader("big" + charname + ".txt")
            );
            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 저장. 없으면 생성

import java.util.HashMap;

public class BigCharFactory {
    // 이미 만들어진 BigChar의 인스턴스를 관리
    private HashMap pool = new HashMap();
    // Singleton 패턴
    private static BigCharFactory singleton = new BigCharFactory();
    // 생성자
    private BigCharFactory() {
    }
    // 유일한 인스턴스를 얻는다
    public static BigCharFactory getInstance() {
        return singleton;
    }
    // BigChar의 인스턴스 생성(공유)
    public synchronized BigChar getBigChar(char charname) {
        BigChar bc = (BigChar)pool.get("" + charname);
        if (bc == null) {
            bc = new BigChar(charname); // 여기에서 BigChar의 인스턴스를 생성
            pool.put("" + charname, bc);
        }
        return bc;
    }
}

 

 

(3) BigString - BigChar를 모은 클래스 for문 bigchars[i] = ~ 에서

                    new Bigchar(string.charAt(i)) 대신 factory.getBigChar(string.charAt(i))를 사용한다. (공유)

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

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 1212123");
            System.exit(0);
        }
        BigString bs = new BigString(args[0]);
        bs.print();
    }
}

  

 

728x90

댓글