개요
메모리 사용을 최소화 해서 가볍게 하기 위한 패턴. 인스턴스를 가능한 공유해 쓸데없이 new(인스턴스 생성)을 하지 않도록 하는게 Flyweight패턴의 핵심이다.
만들어진 인스턴스를 Factory 인스턴스에 저장해놓고 저장된 인스턴스에 대응하는 인스턴스가 필요할 땐 새롭게 인스턴스를 생성하는 것이 아니라 저장된 인스턴스를 사용한다.
역할
Flyweight 역할
취급에 프로그램이 무거워지는 대상으로 인스턴스 공유를 통해 프로그램을 가볍게 하기 좋은 대상. 예제에서는 BigChar 클래스.
FlyweightFactory 역할
Flyweight 인스턴스를 생성하고 요청에 따라 인스턴스를 내어주는 공장 역할. 예제에서는 BigCharFactory 클래스.
Client 역할
FlyweightFactory를 이용해서 Flyweight 역할의 인스턴스를 사용하는 역할. 예제에서는 BigString 클래스
이득 및 유의사항
인스턴스를 공유함으로써 얻을 수 있는 이점은 역시 개요에 작성한대로 인스턴스 생성에 필요한 자원을 아낄 수 있다는 점이다. 인스턴스 생성에 많은 자원이 소모되는 인스턴스 일수록 Flyweight 패턴을 적용함으로써 프로그램을 가볍게 만들 수 있다.
가장 주의해야 할 점은 공유로 인한 일관성의 문제이다. 모든 공유 요소를 포함하는 프로그래밍에서 해결해야 할 문제인데 사용자(Client)가 사용하는 인스턴스가 다른 사용자도 사용이 가능하기 때문에 공유하고 있는 인스턴스를 다른 사용자가 조작하면 내가 기대한 결과가 나오지 않을 수 있는 점이다. 때문에 Flywieght 역할에게 제공해서 공유할 정보를 신중하게 선택해야 한다. 어떤 정보를 기준으로 Flyweight 인스턴스를 생성하고 구분할지는 이를 사용할 목적에 따라 선택해야 한다.
예제 코드
// Flywieght 역할
package flyweight;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BigChar {
private char charname;
private String fontdata;
public BigChar(char charname) {
this.charname = charname;
try {
BufferedReader reader = new BufferedReader(new FileReader("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(IOException e) {
this.fontdata = charname +"?";
}
}
public void print() {
System.out.print(fontdata);
}
}
// FlywieghtFactory 역할
package flyweight;
import java.util.HashMap;
public class BigCharFactory {
private HashMap<Character, BigChar> pool = new HashMap<>();
private static BigCharFactory singleton = new BigCharFactory();
private BigCharFactory() {
}
public static BigCharFactory getInstance() {
return singleton;
}
public synchronized BigChar getBigChar(char charname) {
BigChar bc = pool.get(charname);
if(bc == null) {
bc = new BigChar(charname);
pool.put(charname, bc);
}
return bc;
}
}
// Clinet 역할
package flyweight;
public class BigString {
private BigChar[] bigchars;
public BigString(String str) {
bigchars = new BigChar[str.length()];
BigCharFactory factory = BigCharFactory.getInstance();
for(int i=0; i<bigchars.length; i++) {
bigchars[i] = factory.getBigChar(str.charAt(i));
}
}
public void print() {
for(int i=0; i<bigchars.length; i++) {
bigchars[i].print();
}
}
}
// Tester
package flyweight;
public class FlywieghtTester {
public static void main(String[] args) {
if(args.length == 0) {
System.out.println("Usage: java Main digits");
System.out.println("Example : java Main 1212");
System.exit(0);
}
BigString bs = new BigString(args[0]);
bs.print();
}
}
'디자인 패턴' 카테고리의 다른 글
23. Interpreter 패턴 (0) | 2021.02.15 |
---|---|
21. Proxy 패턴 (0) | 2021.01.11 |
18. Memento 패턴 (0) | 2020.12.30 |
17. Observer 패턴 (0) | 2020.12.29 |
16. Mediator 패턴 (0) | 2020.12.28 |