I assume you've already read the wiki article, so I'll try to give a brief and, hopefully, simple intuition into the flyweight pattern.
The key concept that makes flyweight a "pattern" is the separation of the object state into "intrinsic" and "extrinsic" parts.
Both of these are part of the conceptual "state" of the object, the difference is in how they are represented in the code.
"Intrinsic" state is just your regular fields and properties, while "extrinsic" part of the object is stored externally to the object (doesn't matter where) and passed to the object with each method call.
Consider an artificial example of PlanetSurfaceGravityForceFormula
. It calculates the force of gravity on the surface of the planet for an object of the given mass.
The formula for the gravity is following:

Here, G
, m₁
and r²
are properties of the planet, while m₂
is the property of the object on the surface of the planet.
One way to design the PlanetSurfaceGravityForceFormula
is to have it contain all the state necessary for the calculation:
class PlanetSurfaceGravityForceFormula {
double G, r, m1, m2;
public double calculateForce() {...}
}
In this case, when you need to calculate force, you'll need to create new instance of PlanetSurfaceGravityForceFormula
with all the relevant constants and call the calculateForce
method.
Which is fine, unless you know beforehand that you need to perform the calculation on the limited fixed number of the planets, and only m₂
is expected to change with each call.
So your new design for the PlanetSurfaceGravityForceFormula
is this:
class PlanetSurfaceGravityForceFormula {
double G, r, m1;
public double calculateForce(double m2) {...}
}
See what happened here? m₂
was a part of the intrinsic state before, but now it becomes the extrinsic state, as it's passed from outside for each method call.
This design has several advantages over the previous one:
- It's possible to reuse the same instance of
PlanetSurfaceGravityForceFormula
for different values of m2
- If the planets are fixed and known in advance, it's possible to create static constants of the
PlanetSurfaceGravityForceFormula
for each such planet and use them for calculation
- If the planets are known to be limited, but not known in advance, it's possible to create some kind of
PlanetSurfaceGravityForceFormulaFactory
that returns cached instances of the PlanetSurfaceGravityForceFormula
.
Hopefully this helps to understand the difference between "intrinsic" and "extrinsic" state of the object.
One thing that I'd like to emphasize is that in real life you seldom need to "force" parts of the intrinsic state to become "extrinsic". Usually just following the common sense will yield the best design.
UPD Regarding:
I learn that Static field or function can only use in Static class. However, in this example, static Hashmap and function is declared in non-static class ShapeFactory.
static
keyword in java, frankly, confusing (though less confusing than in C++), as it has different semantics in different context.
Instances of a nested class in java by default retain the reference to the parent class instance, making nested class static
removes this reference, making the nested class behave as the regular top-level class.
Methods, marked as static
can be called from both static and non-static methods, but they have access only to the static fields and methods.
Finally static
fields of the class are "singletons", they are like "global variables", shared throughout your code, even when accessed from different instances of a class. They can be accessed from both regular and static methods.
So, to answer your question:
in this example, static Hashmap and function is declared in non-static class ShapeFactory
Is not strictly true, as ShapeFactory
is the top-level class and it behaves the same way as the static nested classes. From what I can tell, your "abstract factory" implementation is correct, although it's not a flyweight and it technically is a flyweight, where ShapeType
is an intrinsic state and Graphics g, int x, int y, int width, int height, Color color
is extrinsic state of the Shape
.