플라이웨이트 패턴

플라이웨이트 패턴(Flyweight pattern)는 동일하거나 유사한 객체들 사이에 가능한 많은 데이터를 서로 공유하여 사용하도록 하여 메모리 사용량을 최소화하는 소프트웨어 디자인 패턴이다. 종종 오브젝트의 일부 상태 정보는 공유될 수 있는데, 플라이웨이트 패턴에서는 이와 같은 상태 정보를 외부 자료 구조에 저장하여 플라이웨이트 오브젝트가 잠깐 동안 사용할 수 있도록 전달한다.

**예**

**자바**
public enum FontEffect {
BOLD, ITALIC, SUPERSCRIPT, SUBSCRIPT, STRIKETHROUGH
}
public final class FontData {
/*     * A weak hash map will drop unused references to FontData.- Values have to be wrapped in WeakReferences,- because value objects in weak hash map are held by strong references.
*/
private static final WeakHashMap> flyweightData =
new WeakHashMap>();
private final int pointSize;
private final String fontFace;
private final Color color;
private final Set effects;
private FontData(int pointSize, String fontFace, Color color, EnumSet effects) {
this.pointSize = pointSize;
this.fontFace = fontFace;
this.color = color;
this.effects = Collections.unmodifiableSet(effects);
}
public static FontData create(int pointSize, String fontFace, Color color,
FontEffect... effects) {
EnumSet effectsSet = EnumSet.noneOf(FontEffect.class);
for (FontEffect fontEffect : effects) {
effectsSet.add(fontEffect);
}
// 객체를 생성하는 데 드는 비용이나 객체가 차지하는 메모리 공간에 대해 걱정할 필요가 없다.
FontData data = new FontData(pointSize, fontFace, color, effectsSet);
if (!flyweightData.containsKey(data)) {
flyweightData.put(data, new WeakReference(data));
}
// 해시값에 따라 변경불가능한 단일본을 리턴한다.
return flyweightData.get(data).get();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof FontData) {
if (obj == this) {
return true;
}
FontData other = (FontData) obj;
return other.pointSize == pointSize && other.fontFace.equals(fontFace)
&& other.color.equals(color) && other.effects.equals(effects);
}
return false;
}
@Override
public int hashCode() {
return (pointSize * 37 + effects.hashCode() * 13) * fontFace.hashCode();
}
// Getters for the font data, but no setters. FontData is immutable.
}

**C#**
using System.Collections;
using System.Collections.Generic;
using System;
class GraphicChar {
char c;
string fontFace;
public GraphicChar(char c, string fontFace) { this.c = c; this.fontFace = fontFace; }
public static void printAtPosition(GraphicChar c, int x, int y)   {
Console.WriteLine("Printing '{0}' in '{1}' at position {2}:{3}.", c.c, c.fontFace, x, y);
}
}
class GraphicCharFactory {
Hashtable pool = new Hashtable(); // the Flyweights
public int getNum() { return pool.Count; }
public GraphicChar get(char c, string fontFace) {
GraphicChar gc;
string key = c.ToString() + fontFace;
gc = poolkey as GraphicChar;
if (gc == null) {
gc = new GraphicChar(c, fontFace);
pool.Add(key, gc);
}
return gc;
}
}
class FlyWeightExample {
public static void Main(string args) {
GraphicCharFactory cf = new GraphicCharFactory();
// Compose the text by storing the characters as objects.
List text = new List();
text.Add(cf.get('H', "Arial"));    // 'H' and "Arial" are called intrinsic information
text.Add(cf.get('e', "Arial"));    // because it is stored in the object itself.
text.Add(cf.get('l', "Arial"));
text.Add(cf.get('l', "Arial"));
text.Add(cf.get('o', "Times"));
// See how the Flyweight approach is beginning to save space:
Console.WriteLine("CharFactory created only {0} objects for {1} characters.", cf.getNum(), text.Count);
int x=0, y=0;
foreach (GraphicChar c in text) {             // Passing position as extrinsic information to the objects,
GraphicChar.printAtPosition(c, x++, y);   // as a top-left 'A' is not different from a top-right one.
}
}
}

**같이 보기**
 메모이제이션
분류:소프트웨어 디자인 패턴
분류:소프트웨어 최적화