Build Java flyweight factories around clear keys, safe caching rules, and lifecycle awareness so sharing remains correct instead of accidental.
The factory is the operational core of Flyweight. It decides when two requests should receive the same shared instance.
The key must include every field that defines intrinsic identity. If the key is too small, unrelated flyweights are merged incorrectly. If it is too large, sharing disappears.
In Java, common choices include:
HashMap for scoped single-threaded factoriesConcurrentHashMap for shared concurrent lookupThe factory should also have a clear lifecycle. A process-wide cache and a request-scoped cache have very different behavior.
A weak factory is where most Flyweight bugs come from.