학습일지/Language
[Design Pattern] FlyWeight
inspirit941
2020. 12. 15. 08:06
반응형
FlyWeight 패턴
생성 비용이 큰 객체를 공통으로 사용할 수 있도록 만드는 패턴.
- 중복 생성될 가능성이 높은 객체
- 동일한 리소스가 자주 사용될 가능성이 높다는 의미이므로, 공통자원 형태로 관리하는 편이 효율적이다
- 생성비용은 크지만 사용빈도는 낮은 객체
- 이런 경우 매리 객체를 생성해두는 건 낭비. 요청이 있을 때에만 생성해서 제공한다.
FlyWeight 패턴은 위 두 가지 목적을 위해 존재함.
객체 생성을 담당하는 Factory 역할과 객체 관리 역할을 분리하는 편이 유용한 경우도 있으나, 일반적으로는 역할의 크기가 크게 다르지 않으므로 하나의 클래스 안에 있어도 무방하다.
장점
- 많은 객체를 생성할 때 생성시간 / 메모리소모를 줄일 수 있음
- state pattern과 결합이 용이함
단점
- 개별 설정이 불가능. 공통요소의 일부를 빼서 수정하는 식의 설정이 불가능하다.
사용예시
- 워드프로세서의 문자 그래픽 표현을 위한 자료구조
- JDK
- String. (String pool)
- Integer / Boolean / Character / Byte의 ValueOf(). 캐시메모리 확인해서 객체가 있으면 불러오고, 없으면 새로 생성하는 식으로 동작함. primitive값을 boxing하는 것보다 빠르다.
public class TestString1 {
public static void main(String[] args) {
String str1 = new String("test");
String str2 = new String("test");
String str3 = "test";
String str4 = "test";
// 여기서 str1과 str2는 서로 다른 객체를 참조하지만
// str3, str4는 같은 객체를 참조한다.
// 중복 생성을 막기 위해 str3, str4에는 flyweight 패턴이 적용된 사례
}
}
public class TestString1 {
public static void main(String[] args) {
var data1 = new MyData();
data1.x = 10;
data1.y = 11;
data1.name = "test";
var data2 = new MyData();
// data2와 data1은 동일한 객체를 참조하게 된다.
data2 = data1;
// data3은 완전히 다른 객체를 참조.
var data3 = new MyData();
data3.x = 20;
data3.y = 22;
data3.name = "test2";
// 동일한 객체를 참조하므로, data1의 name도 바뀐다.
data2.name = "test3";
data2.x = 7;
// 얕은 복사 = flyweight 패턴이 적용된 사례.
}
}
class MyData {
int x;
int y;
String name;
}
public class Subject {
private String name;
public Subject(String name) {
this.name = name;
}
}
// 리소스 Subject의 생성을 관리하는 객체
public class FlyWeightFactory {
private static Map<String, Subject> map = new HashMap<String, Subject>();
public Subject getSubject(String key) {
Subject subject = map.get(key);
if (subject == null){
subject = new Subject(key);
map.put(key, subject);
System.out.println(key +" 새로 생성");
}
else {
System.out.println(key + " 값 리턴");
}
return subject;
}
}
public class TestFlyWeight2 {
public static void main(String[] args) {
FlyWeightFactory flyWeight = new FlyWeightFactory();
flyWeight.getSubject("a");
flyWeight.getSubject("a");
flyWeight.getSubject("b");
}
}
반응형