Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: Take control with the Proxy design pattern

Take control with the Proxy design pattern

Tutorial Details:

Take control with the Proxy design pattern
Take control with the Proxy design pattern
By: By David Geary
The Proxy design pattern substitutes a proxy for an object, making your apps more efficient
friend of mine -- a medical doctor, no less -- once told me that he convinced a friend to take a college exam for him. Someone who takes the place of someone else is known as a proxy. Unfortunately for my friend, his proxy drank a bit too much the night before and failed the test.
In software, the Proxy design pattern proves useful in numerous contexts. For example, using the Java XML Pack, you use proxies to access Web services with JAX-RPC (Java API for XML-based remote procedure calls). Example 1 shows how a client accesses a simple Hello World Web service:
Example 1. A SOAP (Simple Object Access Protocol) proxy
public class HelloClient {
public static void main(String[] args) {
try {
HelloIF_Stub proxy = (HelloIF_Stub)(new HelloWorldImpl().getHelloIF());
proxy ._setTargetEndpoint(args[0]);
System.out.println( proxy .sayHello("Duke!"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Example 1's code closely resembles the Hello World Web services example included with JAX-RPC. The client obtains a reference to the proxy, and sets the proxy's endpoint (the Web service's URL) with a command line argument. Once the client has a reference to the proxy, it invokes the proxy's sayHello() method. The proxy forwards that method call to the Web service, which often resides on a different machine than that of the client.
Example 1 illustrates one use for the Proxy design pattern: accessing remote objects. Proxies also prove useful for creating expensive resources on demand, a virtual proxy, and for controlling access to objects, a protection proxy.
If you've read my " Decorate Your Java Code " ( JavaWorld, December 2001), you may see similarities between the Decorator and Proxy design patterns. Both patterns use a proxy that forwards method calls to another object, known as the real subject. The difference is that, with the Proxy pattern, the relationship between a proxy and the real subject is typically set at compile time, whereas decorators can be recursively constructed at runtime. But I'm getting ahead of myself.
In this article, I first introduce the Proxy pattern, starting with a proxy example for Swing icons. I conclude with a look at the JDK's built-in support for the Proxy pattern.
Note: In the first two installments of this column -- " Amaze Your Developer Friends with Design Patterns " (October 2001) and " Decorate Your Java Code " -- I discussed the Decorator pattern, which closely relates to the Proxy pattern, so you may wish to look at these articles before proceeding.
The Proxy pattern
Proxy: Control access to an object with a proxy (also known as a surrogate or placeholder).
Swing icons, for reasons discussed in the "Proxy Applicability" section below, represent an excellent choice for illustrating the Proxy pattern. I begin with a short introduction to Swing icons, followed by a discussion of a Swing icon proxy.
Swing icons
Swing icons are small pictures used in buttons, menus, and toolbars. You can also use Swing icons by themselves, as Figure 1 illustrates.
Figure 1. A Swing icon
The application shown in Figure 1 is listed in Example 2:
Example 2. Swing icons
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// This class tests an image icon.
public class IconTest extends JFrame {
private static String IMAGE_NAME = "mandrill.jpg";
private static int FRAME_X = 150, FRAME_Y = 200,
FRAME_WIDTH = 268, FRAME_HEIGHT = 286;
private Icon imageIcon = null, imageIconProxy = null;
static public void main(String args[]) {
IconTest app = new IconTest();
app.show();
}
public IconTest() {
super("Icon Test");
imageIcon = new ImageIcon (IMAGE_NAME);
setBounds(FRAME_X, FRAME_Y, FRAME_WIDTH, FRAME_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
super.paint(g);
Insets insets = getInsets();
imageIcon.paintIcon (this, g, insets.left, insets.top);
}
}
The preceding application creates an image icon -- an instance of javax.swing.ImageIcon -- and then overrides the paint() method to paint the icon.
Swing image-icon proxies
The application shown in Figure 1 is a poor use of Swing image icons because you should use image icons only for small pictures. That restriction exists because creating images is expensive, and ImageIcon instances create their images when they are constructed. If an application creates many large images at once, it could cause a significant performance hit. Also, if the application does not use all of its images, it's wasteful to create them upfront.
A better solution loads images as they become needed. To do so, a proxy can create the real icon the first time the proxy's paintIcon() method is called. Figure 2 shows an application that contains an image icon (on the left) and an image-icon proxy (on the right). The top picture shows the application just after its launch. Because image icons load their images when they are constructed, an icon's image displays as soon as the application's window opens. In contrast, the proxy does not load its image until it is painted for the first time. Until the image loads, the proxy draws a border around its perimeter and displays "Loading image..." The bottom picture in Figure 2 shows the application after the proxy has loaded its image.
Figure 2. An icon (left) and an icon proxy (right)
I've listed the application shown in Figure 2 in Example 3:
Example 3. Swing icon proxies
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// This class tests a virtual proxy, which is a proxy that
// delays loading an expensive resource (an icon) until that
// resource is needed.
public class VirtualProxyTest extends JFrame {
private static String IMAGE_NAME = "mandrill.jpg";
private static int IMAGE_WIDTH = 256, IMAGE_HEIGHT = 256,
SPACING = 5, FRAME_X = 150,
FRAME_Y = 200, FRAME_WIDTH = 530,
FRAME_HEIGHT = 286;
private Icon imageIcon = null, imageIconProxy = null;
static public void main(String args[]) {
VirtualProxyTest app = new VirtualProxyTest();
app.show();
}
public VirtualProxyTest() {
super("Virtual Proxy Test");
// Create an image icon and an image-icon proxy.
imageIcon = new ImageIcon(IMAGE_NAME);
imageIconProxy = new ImageIconProxy (IMAGE_NAME,
IMAGE_WIDTH,
IMAGE_HEIGHT);
// Set the bounds of the frame, and the frame's default
// close operation.
setBounds(FRAME_X, FRAME_Y, FRAME_WIDTH, FRAME_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void paint(Graphics g) {
super.paint(g);
Insets insets = getInsets();
imageIcon.paintIcon (this, g, insets.left, insets.top);
imageIconProxy.paintIcon (this, g,
insets.left + IMAGE_WIDTH + SPACING, // width
insets.top); // height
}
}
Example 3 is nearly identical to Example 2, except for the addition of the image-icon proxy. The Example 3 application creates the icon and the proxy in its constructor, and overrides its paint() method to paint them. Before discussing the proxy's implementation, look at Figure 3, which is a class diagram of the proxy's real subject, the javax.swing.ImageIcon class.
Figure 3. ImageIcon's class diagram. Click on thumbnail to view full-size image.
The javax.swing.Icon interface, which defines the essence of Swing icons, includes three methods: paintIcon() , getIconWidth() , and getIconHeight() . The ImageIcon class implements the Icon interface, and adds methods of its own. Image icons also maintain a description of, and a reference to, their images.
Image-icon proxies implement the Icon interface and maintain a reference to an image icon -- the real subject -- as the class diagram in Figure 4 illustrates.
Figure 4. ImageIconProxy class diagram. Click on thumbnail to view full-size image.
The ImageIconProxy class is listed in Example 4.
Example 4. ImageIconProxy.java
// ImageIconProxy is a proxy (or surrogate) for an icon.
// The proxy delays loading the image until the first time the
// image is drawn. While the icon is loading its image, the
// proxy draws a border and the message "Loading image..."
class ImageIconProxy implements javax.swing.Icon {
private Icon realIcon = null;
boolean isIconCreated = false;
private String imageName;
private int width, height;
public ImageIconProxy(String imageName, int width, int height){
this.imageName = imageName;
this.width = width;
this.height = height;
}
public int getIconHeight() {
return isIconCreated ? height : realIcon.getIconHeight();
}
public int getIconWidth() {
return isIconCreated realIcon == null ? width : realIcon.getIconWidth();
}
// The proxy's paint() method is overloaded to draw a border
// and a message ("Loading image...") while the image
// loads. After the image has loaded, it is drawn. Notice
// that the proxy does not load the image until it is
// actually needed.
public void paintIcon(final Component c,
Graphics g, int x, int y) {
if(isIconCreated) {
realIcon.paintIcon (c, g, x, y);
}
else {
g.drawRect (x, y, width-1, height-1);
g.drawString ("Loading image...", x+20, y+20);
// The icon is created (meaning the image is loaded)
// on another thread.
synchronized(this) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
// Slow down the image-loading process.
Thread.currentThread().sleep(2000);
// ImageIcon constructor creates the image.
realIcon = new ImageIcon(imageName);
isIconCreated = true;
}
catch(InterruptedException ex) {
ex.printStackTrace();
}
// Repaint the icon's component after the
// icon has been created.
c.repaint();
}
});
}
}
}
}
ImageIconProxy maintains a reference to the real icon with the realIcon member variable. The first time the proxy is painted, the real icon is created on a separate thread to allow the rectangle and string to be painted (the call


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
Take control with the Proxy design pattern

View Tutorial:
Take control with the Proxy design pattern

Related Tutorials:

Java Tip 68: Learn how to implement the Command pattern in Java - JavaWorld - February 1999
Java Tip 68: Learn how to implement the Command pattern in Java - JavaWorld - February 1999
 
Create automated and distributed management applications with Jiro technology, Part 1 - JavaWorld February
Create automated and distributed management applications with Jiro technology, Part 1 - JavaWorld February 2000
 
Use Microsoft's Internet Information Server as a Java servlet engine - JavaWorld June 2000
Use Microsoft's Internet Information Server as a Java servlet engine - JavaWorld June 2000
 
Get smart with proxies and RMI - JavaWorld November 2000
Get smart with proxies and RMI - JavaWorld November 2000
 
Take control of the servlet environment, Part 1 - JavaWorld November 2000
Take control of the servlet environment, Part 1 - JavaWorld November 2000
 
J2EE project dangers! - JavaWorld March 2001
J2EE project dangers! - JavaWorld March 2001
 
Clean up your wire protocol with SOAP, Part 4 - JavaWorld July 2001
Clean up your wire protocol with SOAP, Part 4 - JavaWorld July 2001
 
Explore the Dynamic Proxy API
Explore the Dynamic Proxy API
 
Take control with the Proxy design pattern
Take control with the Proxy design pattern
 
Design patterns make for better J2EE apps
Design patterns make for better J2EE apps
 
Take command of your software
Take command of your software
 
Effort on the edge, Part 1
Effort on the edge, Part 1
 
Simply Singleton
Simply Singleton
 
Jini Starter Kit 2.0 tightens Jini's security framework
Jini Starter Kit 2.0 tightens Jini's security framework
 
Impressive !
Impressive !
 
Interesting concept ...
Interesting concept ...
 
Very interesting
Very interesting
 
Second-generation aspect-oriented programming
Second-generation aspect-oriented programming
 
Dynamic Delegation and Its Applications
Dynamic Delegation and Its Applications The Proxy pattern is an important and widely used design pattern in object-oriented programming. Do you ever use Proxy in Java since its introduction in JDK 1.3? A dynamic proxy class is a class that implements a l
 
Open Source Web Frameworks in Java
Open Source Web Frameworks in Java Open Source Web Frameworks in Java Struts Struts Frame work is the implementation of Model-View-Controller (MVC) design pattern for the JSP. Struts is maintained as a part of Apache Jakarta project and is open
 
Site navigation
 

 

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright © 2006. All rights reserved.