Design Patterns and Frameworks – Flyweight
Oliver Haase
Description
I Classification: Object-based structural pattern
I Purpose: Use small-grained objects together, to avoid instantiation of a large number of objects.
“Any fool can write code that a computer can understand.
Good programmers write code that humans can understand.”
— Martin Fowler.
Oliver Haase Emfra — Flyweight 2/12
Motivation
I Imagine a text processor that represents text documents consisting of pages, rows, words, and characters.
I for homogeneity, it would be nice to treat the concepts of pages, rows, words, and characters similarly, in particular as objects.
I Problem: A book with 300 pages can easily contain 840 000 characters
→ huge overhead if modelled as 840 000 regular objects!
Idea
I Divide object state into intrinsicandextrinsic state, such that there is only a small number of distinct objects with different intrinsic states.
I Share these flyweight objects.
I Feed them with extrinsic state for operation invocations.
CharacterFlyweight Objects
intrinsic state: character code (e.g. Unicode)
extrinsic state: font, text style (bold, italics, regular), position
Oliver Haase Emfra — Flyweight 4/12
Description
I Applicability: Use the flyweight pattern only if all of the following apply
I An application uses a large number of objects.
I The memory consumption forbids instantiation of individual objects.
I A big part of the object state can be moved into the context (can be made extrinsic).
I Removal of the extrinsic state results in a small number of distinct objects.
I Thr application does not depend on the object identity.
Structure
Oliver Haase Emfra — Flyweight 6/12
Participants
I Flyweight: declares operations that get fed with the extrensic state
I ConcreteFlyweight:
I implements theFlyweightinterface
I keeps the intrinsic state of the (shared) object
I UnsharedConcreteFlyweight: Possibly, some implementations of Flyweight are not shared — typically more coarse-grained objects on a higher layer of the application. The objects can keep not only their intrinsic, but their complete state.
I FlyweightFactory: creates and maintains the flyweight objects.
I Client:
I has references to the flyweight objects
I keeps or computes the objects’ extrinsic state
Interactions
I Intrinsic and extrinsic state must be clearly distinguishable.
Flyweight objects store intrinsic state, clients store or compute extrinsic state and supply it into flyweight’s operations.
I Clients don’t create flyweight objects directly. A flyweight factory makes sure flyweight objects are correctly shared.
Oliver Haase Emfra — Flyweight 8/12
Consequences
I Reduced memory consumption comes at the cost of increased runtime, because client has to compute or access stored extrinsic state information, and pass it into flyweight objects.
I Memory saving depends on
I degree of reduction of objects;
I size of intrinsic state;
I whether extrinsic state is stored or calculated.
Extrinsic State
I Applicability depends on how easily extrinsic state information can be identified and pulled out.
I Benefit (in terms of memory consumption) depends on whether the amount of extrinsic state for all flyweight objects equals the original state information or not.
Example →character flyweight objects:
intrinsic state: Character code (e.g. Unicode) extrinsic state: font, text style, position
Client doesn’t have to store font and text style per flyweight object, but stores these attributes per bigger chunks of text.
Oliver Haase Emfra — Flyweight 10/12
Related Patterns
I Flyweight often combined with composite pattern, to build hierarchy of objects with shared (flyweight) leaves.
I →State and→Strategy objects are preferably implemented as flyweight objects.
Closing Remarks
I Normally, patterns are intended to keep design simply, to reduce dependencies, to reduce number of classes, etc.
→ simplicity,clarity,maintainability, & friends
I sometimes — though not always — at the expense of reduced efficiency
I In contrast, flyweight pattern motivated by efficiency considerations
→ relevance can be expected to decrease as main memory continously gets cheaper
Oliver Haase Emfra — Flyweight 12/12