
We want to draw a small folder icon with a name under it for each person in an organization. This means no matter the number of icons it is the same graphical image. If we have two icons, one for "isSelected" and one for "notSelected" we have limited our use of resources. A FolderFactory class is created that returns either the selected or unselected folder drawing class. The FolderFactory class does not create additional instances once one of each of them has been created. In the following code example, both instances are created at the outset and then one or the other is returned.
class FolderFactory
{
Folder unSelected, Selected;
public FolderFactory()
{
Color brown = new Color(0x5f5f1c);
Selected = new Folder(brown);
unSelected = new Folder(Color.yellow);
}
//-------------------------------------
public Folder getFolder(boolean isSelected)
{
if(isSelected)
return Selected;
else
return unSelected;
}
} If more instances existed, the FolderFactory could keep a table of the instances already created and only create new instances if they aren't in the table. The extrinsic data in this case is the name attached to the folder and the co-ordinates of the folder. The Folder class creates an instance with one of two background colours and the public Draw method draws the folder at the co-ordinates specified.
class Folder extends JPanel
{
private Color color;
final int W = 50, H = 30;
public Folder(Color c)
{
color = c;
}
//------------------------------------------------------
public void Draw(Graphics g, int tx, int ty, String NAME)
{
g.setColor(Color.black); ;//outline
g.drawRect(tx, ty, W, H);
g.drawString(name, tx, ty + H + 15); //title
g.setColor(color); //fill rectangle
g.fillRect(tx+1, ty+1, W-1, H-1);
g.setColor(Color, lightGray); //bend line
g.drawLine(tx+1, ty+H-5, tx+W-1, ty+H-5);
g.setColor(Color.black); //shadow lines
g.drawLine(tx, ty+H+1, tx+w-1, ty+H+1);
g.drawLine(tx+w+1, ty, tx+W+1, ty+H);
g.setColor(Color.white); //highlight lines
g.drawLine(tx+1, ty+1, tx+W-1, ty+1);
g.drawLine(tx+1, ty+1, tx+1, ty+H-1);
}
}
For the purpose of these notes, the paint and mouseMoved events will not be defined. All of the classes can be viewed at the James Cooper's website. This example shows how the Flyweight design pattern can be used to minimize system resources by decreasing the number of unique instances of a class.

When a tone generator is requested, it is connected to the A party (the subscriber line). When the tone is no longer needed, it is disconnected so that another client can use it. The switch maintains the reference to the flyweights. The Flyweight design pattern is intended to save cost in this case by reducing the number of tone generators required and reducing the physical space required for equipment.
Flyweight is often combined with the Composite pattern to implement a directed-acyclic graph with shared leaf nodes. State and Strategy should often be implemented as Flyweights. (Gamma, 1995)
The more intrinsic states there are, the more savings occur. If a large number of extrinsic states must be computed, the space savings occur at the expense of computation time.
The Flyweight design pattern is intended to use sharing to support large numbers of objects efficiently. Flyweight should be used in cases where many objects share simliar data except for a few items, which can be passed through parameters. A Flyweight has both an intrinsic and an extrinsic state. The instrinsic state is stored in the Flyweight and consists of information that is independent of the Flyweight's context. The extrinsic state is stored in the client. The extrinsic state is the parameters that are passed into the methods. Flyweight offsets run-time costs with storage savings.
We want to display an image on a JPanel when it is loaded. The loading will be deferred to the class ImageProxy which draws a rectangle around the image area until the loading is complete.
public class ProxyDisplay extends JxFrame
{
public ProxyDisplay()
{
super("Display proxied image");
JPanel p = new JPanel();
getContentPane().add(p);
p.setLayout(new BorderLayout());
ImageProxy image = new ImageProxy(this, "elliot.jpg", 321,271);
p.add("Center", image);
setSize(400,400);
setVisible(true);
}
The instance of ImageProxy is created and added to the JPanel in exactly the same way as an actual image. ImageProxy starts the loading process and creates a MediaTracker object to follow the loading process within the constructor:
public ImageProxy(JFrame f, String filename, int w, int h)
{
height = h;
width = w;
frame = f;
tracker = new MediaTracker(f);
img = Toolkit.getDefaultToolkit().getImage(filename);
tracker.addImage(img, 0); //watch for image loading
imageCheck = new Thread(this);
imageCheck.start(); //start 2nd thread monitor
//this begins the actual image loading
try{
tracker.waitForId(0,1);
{
catch(InterruptedException e){}
}
The waitForID method actually initiates loading. In this case, the minimum wait time is 1 millisecond to minimize the apparent program delays. The constructor also creates a thread to check the loading staus every few milliseconds. This code can be found at at the James Cooper's website. This example illustrates how the ImageProxy class acts as a placeholder for a more complex image until the object has completed processing.

Again we can look to the telecommunications for an example of an everyday use of a design pattern. Here, the Proxy pattern applies. In this case:
Proxy introduces a level of indirection when accessing an object. This indirection can be used for security or to forward the information to a different address space. In this case, the proxy acts as a remote proxy which hides the actual number being dialed.
Adapter provides a different interface to the object it adapts, while proxy provides the same interface as its subject. A proxy's interface can be a subset of its subject's.
Decorators can have simliar implementations as proxies but they have a different purpose. A decorator adds one or more responsibilites to an object, whereas a proxy controls access to an object.
Proxy has effectively 3 uses:
Proxy is highly useful in all three forms. Its use as a memory-saving object allows for faster applications and it's use as a remote object allows for more secure applications.