플라이웨이트 패턴

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

 예 

 자바 
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 = pool[key] 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.
 }
 }
}
 같이 보기 
 메모이제이션

분류:소프트웨어 디자인 패턴
분류:소프트웨어 최적화