Flyweight

When you have Composites, you often have collections of similar objects. Perhaps they each have some unique state, such as their position on a page or their textual content. But sometimes, the thing that makes them unique is the specific selection of different regular elements. They may have a distinctive combination of font and colour, or perhaps the image and location are unusual. If each object is unique only in these ways, we have duplicated common information and wasted resources.

Instead of capturing the non-unique data per object, present a palette of options for Clients to call upon as necessary. The Flyweight pattern calls these options ConcreteFlyweight objects, which makes little sense to me as they are the heavier objects we try to avoid duplicating.

In graphical rendering, triangle mesh objects or sprites count as ConcreteFlyweight objects because you refer to them rather than holding a full mesh or sprite in each Client. In some documents, fonts, images such as logos, and even repeated composites can be shared in this manner—house planning software often uses a palette of doors, windows, and furniture items.

One way of thinking about the Flyweight is that instead of handing off how to do a thing to another object as you do with Strategy, you hand off being a thing instead. This is the nominalisation of attribute, but not identity. So, when using the ConcreteFlyweight, invocations will frequently require a context such that the ConcreteFlyweight can perform as if it were the fully-fledged instance when it acts on behalf of the Client.

The pattern is only practical when:

  • You have a collection of objects
  • Those objects have internal state
  • Those objects have costly attributes in common

Without many objects, there cannot be attributes in common. Without the state, there is no call for unique Client objects. If they aren’t unique, you could reference the ConcreteFlyweight directly.

Client objects are stateful, while the ConcreteFlyweight objects are stateless. You might also think of them as Prototypes you never clone.

If your composite does not require parents, you can use a ConcreteFlyweight as a leaf in your hierarchy, reducing costs.

“I have a house. Although, yes, I share it with quite a few others.”