[Design Pattern] Flyweight pattern
Flyweight pattern이란?
Flyweight pattern은 비용이 큰 자원을 공통으로 사용할 수 있도록 만드는 패턴입니다.
비용이 크다는 것은 두 가지로 나누어 생각할 수 있습니다.
1. 중복 생성될 가능성이 높은 경우
동일한 자원이 자주 사용될 가능성이 높은 경우입니다.
이런 자원은 공통 자원 형태로 관리하고 요청이 있을 때 제공해주는 것이 좋습니다.
2. 자원 생성 비용은 큰데 사용빈도가 낮은 경우
자주 생성하지 않는 데 사용빈도가 낮은 자원을 항상 생성하는 것은 낭비겠죠.
즉 , 생성된 객체를 생성한 후 저장하여 재활용하는 팩토리를 기반으로 합니다.
객체가 요청될 때마다 팩토리는 객체가 이미 생성되었는지 확인하기 위해 객체를 찾습니다.
있는 경우 기존 오브젝트가 리턴됩니다. 그렇지 않으면 새 오브젝트가 작성, 저장 및 리턴됩니다.
Flyweight pattern의 특징
1. 메모리 사용 공간의 낭비를 줄일 수 있습니다.
Flyweight Pattern with Java
public class Car {
private String name;
public Car(String data) {
this.name = data;
}
public String getName() {
return name;
}
}
public class CarFactory {
Map pool;
public CarFactory() {
pool = new HashMap();
}
public Car getCar(String key) {
Car car = (Car) pool.get(key);
if (car == null) {
car = new Car(key);
pool.put(key, car);
System.out.println("새로 생성 : " + key);
} else {
System.out.println("재사용 : " + key);
}
return car;
}
}
public class Client {
public static void main(String[] args) {
CarFactory factory = new CarFactory();
System.out.println(factory.getCar("Car A"));
System.out.println(factory.getCar("Car B"));
System.out.println(factory.getCar("Car C"));
System.out.println(factory.getCar("Car B"));
System.out.println(factory.getCar("Car A"));
System.out.println(factory.getCar("Car A"));
}
}
//result
새로 생성 : Car A
k.bs.designpatternsp.pattern.flyweight.ja.car.Car@6e0be858
새로 생성 : Car B
k.bs.designpatternsp.pattern.flyweight.ja.car.Car@61bbe9ba
새로 생성 : Car C
k.bs.designpatternsp.pattern.flyweight.ja.car.Car@610455d6
재사용 : Car B
k.bs.designpatternsp.pattern.flyweight.ja.car.Car@61bbe9ba
재사용 : Car A
k.bs.designpatternsp.pattern.flyweight.ja.car.Car@6e0be858
재사용 : Car A
k.bs.designpatternsp.pattern.flyweight.ja.car.Car@6e0be858
java에서 적용된 예 찾기
public static void main(String[] args){
String s = "hello";
String s1 = new String("hello");
String s2 = "hello";
System.out.println("s == s1 ? " + (s == s1));
System.out.println("s == s2 ? " + (s == s2));
}
//result
s == s1 ? false
s == s2 ? true
위와 같은 결과가 나오는 이유는
String Pool이라는 공간에 문자열을 저장하기 때문입니다.
String타입의 객체를 선언할 때 new 연산자가 아닌 대입 연산자를 통해서 값을 선언하면,
JVM이 String Pool에서 같은 문자열이 있는지 우선 찾게 됩니다.
만약 같은 문자열이 존재하지 않는다면 새로운 문자열을 생성하고 같은 문자열이 있다면
새로운 객체를 생성하는 것이 아닌 참조하게 됩니다.
Java의 String클래스가 Flyweight패턴이 적용된 것입니다.
Flyweight Pattern with Kotlin
예) 글리프 (캐릭터를 나타내는 그림)
interface Glyph {
var position: Int
fun show(): String
}
data class GlyphCode(val code: String)
class GlyphFlyweight(private val code: GlyphCode, override var position: Int = 0) : Glyph {
override fun show(): String = code.code
}
class GlyphFactory(private val glyphCodes: MutableMap<String, GlyphCode> = mutableMapOf()) {
fun retrieveGlyph(code: String): Glyph {
// create Glyph Code if it does not exists
if (code !in glyphCodes) glyphCodes[code] = GlyphCode(code)
// create and return a new Glyph with the shared cached Glyph Code which corresponds to the requested code
return GlyphFlyweight(glyphCodes[code] ?: GlyphCode(code))
}
}
MutableMap을 계속 생성하게 되면 자원 낭비가 심하게 됩니다.
ClyphFactory는 GlyphFlyweight 인스턴스를 만들 때 계속하여 같은 MutableMap을 재사용합니다.
정리
FlyWeight Pattern은
1. 중복 생성될 가능성이 높은 경우
2. 자원 생성 비용은 큰데 사용빈도가 낮은 경우
자원을 재사용하는 패턴입니다
샘플 보러 가기
https://github.com/qjatjr1108/DesignPattern
'DesignPattern' 카테고리의 다른 글
[Design Pattern] Observer Pattern (0) | 2019.10.15 |
---|---|
[Design Pattern] Strategy Pattern (4) | 2019.10.11 |
[Design Pattern] Composition Pattern (2) | 2019.10.10 |
[Design Pattern] Bridge Pattern (4) | 2019.10.10 |
[Design Pattern] Proxy Pattern (4) | 2019.10.08 |
댓글