Listen to this post
Use sharing to support large numbers of fine-grained objects efficiently. (GoF)
Font systems model each letter with a different class that is capable of scaling, micro-positioning, kerning, and other, often heavyweight, behaviors. If a large document contains many examples of, say, the letter A, then creating an instance of A for each appearance would be wasteful since all A’s would behave the same way; the only difference would be their location (such as row and column). The Flyweight suggests pulling out the varying state position into lightweight objects, all of which defer to the single instance of the letter for all behaviors.
Qualities and principles
The Flyweight is a good example of the separation of concerns. The varying state is one concern, the consistent behavior is another. Clients couple only to the state object, whereas the state objects couple to the abstraction of the behavior (Letter, in the example). Any number of state objects can exist without requiring more behavior objects, eliminating redundant resource consumption.
The Flyweight (CharPosition in the example) can easily be tested against a Mock of the behavioral object.
Questions and concerns
The Flyweight increases delegation in the system to reduce resource consumption, but does create more use of the stack, the VAT, etc. You sacrifice a bit of performance to avoid wasting memory.
The Flyweight can be used to eliminate any manner of client-specific state from coupling to any kind of behavior, thus whenever a heavyweight entity is created, the Flyweight should be considered as a possibility. A good example of this is the Façade.
The Flyweight assumes that all reuse of the behavior object is consistent. If there are exceptions to this, an Adapter or Proxy can be used to resolve the differences. The behavior objects are often Singletons.