Flyweight Design Pattern

COMP 310  Java Resources  Eclipse Resources

(Back to Design Patterns)

Summary: The Flyweight Design Pattern is useful when there is the need for many, many objects to exist that share some information or similarly, when a set of obgjects can be re-used to service many different client objects.

The Flyweight Design Pattern enables the effecient usage of common data and behaviors in a large system. Several thousand or even several hundred thousand objects might be needed, and this is usually very memory-consuming to keep track of. Given certain constraints, it is possible to reduce this problem greatly and make the presence of so many objects possible. If all of the objects share some intrinsic, invariant information that is constant among all of them, it can be removed from each object, and referenced. This eliminates the redundancy of having to repeat the same invariant, intrinsic information for each object, so instead of storing the same information n times for n objects, it is only stored once. This object that contains all of the intrinsic information is called a flyweight object.

It is possible for a flyweight to have extrinsic information as well. This information must be stateless and determined by context, having no stored values, but values that can be calculated on the spot. This separation into extrinsic and intrinsic information allows great numbers of similar objects to exist, differing only in the context in which they exist.

The more information that is stateless and intrinsic that is shared between the objects in the flyweight, the better. This allows for greater savings in memory, since less context information needs to be passed around. If the extrinsic properties include some kind of state information (it is acceptable for the extrinsic properties to have state information, it is only the intrinsic properties in the flyweight that cannot possess state information) or if there is a large amount of extrinsic information, there is increased overhead from having to calculate or transfer the extrinsic information. The best case occurs when extrinsic state information can be computed, and does not need to be stored. One considerable drawback is that because of this generalization and sharing of intrinsics, it makes objects indistinguishable from one another, so we do not have handles to them any more.

The different components involved in the Flyweight Pattern are the Flyweight, the ConcreteFlyweight, the FlyweightFactory and the Client.

  • The Flyweight itself is the set of intrinsic information that a set of objects share in common. It is abstract.
  • The ConcreteFlyweight is a subclass of the Flyweight, and contains all of its information, as well as how to calculate extrinsic information for a particular (yet arbitrary) object. It is shared among more than one object.
  • The FlyweightFactory serves to dispense particular flyweights requested. When a Flyweight with certain properties is requested, it checks to see if one already exists, and if so, returns that flyweight. If the requested flyweight does not exist, it creates the requisite flyweight, stores it, and then returns it.
  • The Client, in creating a new object, must assign a flyweight to it, so it asks the FlyweightFactory for a particular flyweight, receives that flyweight, and creates a reference to it in the object it is creating.

Figure 1: UML diagram of flyweight design pattern
Flyweight Example UML
UML diagram of flyweight example

 

In the above example, the Client uses the FlyweightFactory to create the flyweights it needs. When the Client needs the flyweight to do something, it calls the appropriate method of the flyweight, passing it any extrinsic state information it might need as its context. The Flyweight factory maintains a pool of instantiated flyweights. When the client requests a shareable flyweight, the factory first searches the pool to see if there is already one available. If it is, the factory simply returns that instance. Otherwise it instantiates a new flywieght, adds it to the pool and returns a reference to the client.

EXAMPLE 1: Flyweight Demo

Click here (Flyweight.zip) to download a fully functional demo that uses flyweights. This example is the classic "BallWorld" with colored balls that bounce around the screen using an abstract update strategy to determine their behaviors. The balls use a flyweight to give them shared radii, color and update strategy information and behavior. The file also contains StructureBuilder and JBuilder project files.

Figure 2: UML diagram of flyweight demo code
Flyweight Demo UML
UML diagram of flyweight demo

 

In short, the demo animates abstractly equivalent concrete instantiations of ABall, each of which has their on-screen behavior controlled by a concrete instantiation of the AStrategy strategy. The flwyweight-related parts of the demo are

  • Ball -- A concrete ABall that uses a shared flyweight to determine its behavior
  • BallFlyweight -- The flyweight class that determines a Ball's radius, color, and update strategy. This is a shared flyweight, so all balls share the same radius, color and update strategy.
  • FlyweightFactory -- A factory that creates BallFlyweights with specific radii, colors, containers, and strategies. If a flyweight with the given specifications already exists, the same flyweight is reused, otherwise a new instance is created.
See the code documentation for further details.

 

 


Originally published in Connexions (CNX): https://web.archive.org/web/20130914054355/http://cnx.org/content/m26103/latest/

© 2023 by Stephen Wong