Flyweight pattern
![Abbozzo](http://upload.wikimedia.org/wikipedia/commons/thumb/0/0e/Puzzle_stub.svg/45px-Puzzle_stub.svg.png)
Nella programmazione ad oggetti, il flyweight è uno dei pattern fondamentali, definiti originariamente dalla Gang of Four.
Flyweight è un Design pattern che permette di separare la parte variabile di una classe dalla parte che può essere riutilizzata, in modo tale da condividere quest'ultima fra differenti istanze. L'oggetto Flyweight deve essere un oggetto immutabile, per permettere la condivisione tra diversi client e thread.
Esempio
Progettando un word processor si potrebbe creare un oggetto per ogni carattere digitato. L'oggetto glifo dovrebbe contenere informazioni come il font, la dimensione e il colore di ogni carattere. Il problema è che un testo lungo potrebbe contenere migliaia di caratteri, e oggetti. Il pattern Flyweight risolve il problema creando un nuovo oggetto per memorizzare quelle informazioni che sono condivise da tutti i caratteri con la stessa formattazione. Memorizzando le informazioni una volta sola si ha un grosso risparmio di memoria.
Java
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<FontData, WeakReference<FontData>> flyweightData = new WeakHashMap<FontData, WeakReference<FontData>>(); private final int pointSize; private final String fontFace; private final Color color; private final Set<FontEffect> effects; private FontData(int pointSize, String fontFace, Color color, EnumSet<FontEffect> 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<FontEffect> effectsSet = EnumSet.noneOf(FontEffect.class); for (FontEffect fontEffect : effects) { effectsSet.add(fontEffect); } // We are unconcerned with object creation cost, we are reducing overall memory consumption FontData data = new FontData(pointSize, fontFace, color, effectsSet); if (!flyweightData.containsKey(data)) { flyweightData.put(data, new WeakReference(data)); } // return the single immutable copy with the given values return flyweightData.get(data).get(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; FontData other = (FontData) obj; if (color == null) { if (other.color != null) return false; } else if (!color.equals(other.color)) return false; if (effects == null) { if (other.effects != null) return false; } else if (!effects.equals(other.effects)) return false; if (fontFace == null) { if (other.fontFace != null) return false; } else if (!fontFace.equals(other.fontFace)) return false; if (pointSize != other.pointSize) return false; return true; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((color == null) ? 0 : color.hashCode()); result = prime * result + ((effects == null) ? 0 : effects.hashCode()); result = prime * result + ((fontFace == null) ? 0 : fontFace.hashCode()); result = prime * result + pointSize; return result; } // 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 = (GraphicChar)pool[key]; 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<GraphicChar> text = new List<GraphicChar>(); 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. } } }
Voci correlate
- Design pattern
Altri progetti
Altri progetti
- Wikimedia Commons
Wikimedia Commons contiene immagini o altri file su Flyweight pattern
V · D · M | |
---|---|
Creazionali | Abstract factory · Builder · Factory · Prototype · Singleton |
Strutturali | Adapter · Bridge · Composite · Container pattern · Decorator · Façade · Flyweight · Proxy |
Comportamentali | Chain-of-responsibility · Command · Interpreter · Iterator · Mediator · Memento · Observer · State · Strategy · Template method · Visitor |
Pattern di concorrenza | Active object · Balking · Binding properties · Double-checked locking · Event-based asynchronous · Guarded suspension · Join · Lock · Monitor · Proactor · Reactor · Read write lock · Scheduler · Thread pool · Thread-local storage |
Pattern architetturali | Front controller · Interceptor · MVC · n-tier · Specification · Publish–subscribe · Naked objects · Service locator · Active record · Identity map · Data Access Object · Data transfer object · ADR · Inversione del controllo |
Altri pattern | Blackboard · Business delegate · Composite entity · Dependency injection · Intercepting filter · Lazy loading · Mock object · Null object · Object pool · Servant · Twin · Type tunnel |
Libri | Design Patterns · Enterprise Integration Patterns |
Persone | Christopher Alexander · Erich Gamma · Ralph Johnson · John Vlissides · Grady Booch · Kent Beck · Ward Cunningham · Martin Fowler · Robert Martin · Jim Coplien · Douglas Schmidt · Linda Rising |
Comunità | The Hillside Group · The Portland Pattern Repository |
![](http://upload.wikimedia.org/wikipedia/commons/thumb/7/77/Computer_n_screen.svg/24px-Computer_n_screen.svg.png)