Programming - Flyweight Structural Design Pattern
Use sharing to support large numbers of fine-grained objects
efficiently.
The classes and/or objects participating in this pattern
are:
-
Flyweightand
- declares an interface through which flyweights can
receive and act on extrinsic state.
-
ConcreteFlyweightand and
- implements the Flyweight interface and adds storage
for intrinsic state, if any. A ConcreteFlyweight object
must be sharable. Any state it stores must be intrinsic,
that is, it must be independent of the ConcreteFlyweight
object's context.
-
UnsharedConcreteFlyweight
- not all Flyweight subclasses need to be shared. The
Flyweight interface enables sharing, but it
doesn't enforce it. It is common for
UnsharedConcreteFlyweight objects to have
ConcreteFlyweight objects as children at some level in
the flyweight object structure (as the Row and Column
classes have).
-
FlyweightFactoryand and
- creates and manages flyweight objects
- ensures that flyweight are shared properly. When a
client requests a flyweight, the FlyweightFactory objects
supplies an existing instance or creates one, if none
exists.
-
Clientand and
- maintains a reference to flyweight(s).
- computes or stores the extrinsic state of
flyweight(s).
using System;
using System.Collections;
namespace DoFactory.GangOfFour.Flyweight.Structural
{
// MainApp test application
class MainApp
{
static void Main()
{
// Arbitrary extrinsic
state
int extrinsicstate =
22;
FlyweightFactory f = new
FlyweightFactory();
// Work with different
flyweight instances
Flyweight fx =
f.GetFlyweight("X");
fx.Operation(--extrinsicstate);
Flyweight fy =
f.GetFlyweight("Y");
fy.Operation(--extrinsicstate);
Flyweight fz =
f.GetFlyweight("Z");
fz.Operation(--extrinsicstate);
UnsharedConcreteFlyweight
uf = new
UnsharedConcreteFlyweight();
uf.Operation(--extrinsicstate);
// Wait for user
Console.Read();
}
}
// "FlyweightFactory"
class FlyweightFactory
{
private Hashtable flyweights = new
Hashtable();
// Constructor
public FlyweightFactory()
{
flyweights.Add("X", new
ConcreteFlyweight());
flyweights.Add("Y", new
ConcreteFlyweight());
flyweights.Add("Z", new
ConcreteFlyweight());
}
public Flyweight GetFlyweight(string
key)
{
return((Flyweight)flyweights[key]);
}
}
// "Flyweight"
abstract class Flyweight
{
public abstract void Operation(int
extrinsicstate);
}
// "ConcreteFlyweight"
class ConcreteFlyweight : Flyweight
{
public override void Operation(int
extrinsicstate)
{
Console.WriteLine("ConcreteFlyweight:
" + extrinsicstate);
}
}
// "UnsharedConcreteFlyweight"
class UnsharedConcreteFlyweight : Flyweight
{
public override void Operation(int
extrinsicstate)
{
Console.WriteLine("UnsharedConcreteFlyweight:
" +
extrinsicstate);
}
}
}
Output expected:
ConcreteFlyweight: 21
ConcreteFlyweight: 20
ConcreteFlyweight: 19
UnsharedConcreteFlyweight: 18
and