Programming Tutorials Browser Tutorials Articles Struts Tutorials Hibernate Tutorials

  Tutorial: good design pattern

good design pattern

Tutorial Details:

Follow the Chain of Responsibility
Follow the Chain of Responsibility
By: By David Geary
Run through server-side and client-side CoR implementations
recently switched to Mac OS X from Windows and I'm thrilled with the results. But then again, I only spent a short five-year stint on Windows NT and XP; before that I was strictly a Unix developer for 15 years, mostly on Sun Microsystems machines. I also was lucky enough to develop software under Nextstep, the lush Unix-based predecessor to Mac OS X, so I'm a little biased.
Aside from its beautiful Aqua user interface, Mac OS X is Unix, arguably the best operating system in existence. Unix has many cool features; one of the most well known is the pipe , which lets you create combinations of commands by piping one command's output to another's input. For example, suppose you want to list source files from the Struts source distribution that invoke or define a method named execute() . Here's one way to do that with a pipe:
grep "execute(" `find $STRUTS_SRC_DIR -name "*.java"` | awk -F: '{print $1}'
The grep command searches files for regular expressions; here, I use it to find occurrences of the string execute( in files unearthed by the find command. grep 's output is piped into awk , which prints the first token?delimited by a colon?in each line of grep 's output (a vertical bar signifies a pipe). That token is a filename, so I end up with a list of filenames that contain the string execute( .
Now that I have a list of filenames, I can use another pipe to sort the list:
grep "execute(" `find $STRUTS_SRC_DIR -name "*.java"` | awk -F: '{print $1}' | sort
This time, I've piped the list of filenames to sort . What if you want to know how many files contain the string execute( ? It's easy with another pipe:
grep "execute(" `find $STRUTS_SRC_DIR -name "*.java"` | awk -F: '{print $1}' | sort -u | wc -l
The wc command counts words, lines, and bytes. In this case, I specified the -l option to count lines, one line for each file. I also added a -u option to sort to ensure uniqueness for each filename (the -u option filters out duplicates).
Pipes are powerful because they let you dynamically compose a chain of operations. Software systems often employ the equivalent of pipes (e.g., email filters or a set of filters for a servlet). At the heart of pipes and filters lies a design pattern: Chain of Responsibility (CoR).
Note: You can download this article's source code from Resources .
CoR introduction
The Chain of Responsibility pattern uses a chain of objects to handle a request, which is typically an event. Objects in the chain forward the request along the chain until one of the objects handles the event. Processing stops after an event is handled.
Figure 1 illustrates how the CoR pattern processes requests.
Figure 1. The Chain of Responsibility pattern
In Design Patterns , the authors describe the Chain of Responsibility pattern like this:
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
The Chain of Responsibility pattern is applicable if:
You want to decouple a request's sender and receiver
Multiple objects, determined at runtime, are candidates to handle a request
You don't want to specify handlers explicitly in your code
If you use the CoR pattern, remember:
Only one object in the chain handles a request
Some requests might not get handled
Those restrictions, of course, are for a classic CoR implementation. In practice, those rules are bent; for example, servlet filters are a CoR implementation that allows multiple filters to process an HTTP request.
Figure 2 shows a CoR pattern class diagram.
Figure 2. Chain of Responsibility class diagram
Typically, request handlers are extensions of a base class that maintains a reference to the next handler in the chain, known as the successor . The base class might implement handleRequest() like this:
public abstract class HandlerBase {
...
public void handleRequest(SomeRequestObject sro) {
if(successor != null)
successor.handleRequest(sro);
}
}
So by default, handlers pass the request to the next handler in the chain. A concrete extension of HandlerBase might look like this:
public class SpamFilter extends HandlerBase {
public void handleRequest(SomeRequestObject mailMessage) {
if(isSpam(mailMessage)) { // If the message is spam
// take spam-related action. Do not forward message.
}
else { // Message is not spam.
super.handleRequest(mailMessage); // Pass message to next filter in the chain.
}
}
}
The SpamFilter handles the request (presumably receipt of new email) if the message is spam, and therefore, the request goes no further; otherwise, trustworthy messages are passed to the next handler, presumably another email filter looking to weed them out. Eventually, the last filter in the chain might store the message after it passes muster by moving through several filters.
Note the hypothetical email filters discussed above are mutually exclusive: Ultimately, only one filter handles a request. You might opt to turn that inside out by letting multiple filters handle a single request, which is a better analogy to Unix pipes. Either way, the underlying engine is the CoR pattern.
In this article, I discuss two Chain of Responsibility pattern implementations: servlet filters, a popular CoR implementation that allows multiple filters to handle a request, and the original Abstract Window Toolkit (AWT) event model, an unpopular classic CoR implementation that was ultimately deprecated.
Servlet filters
In the Java 2 Platform, Enterprise Edition (J2EE)'s early days, some servlet containers provided a handy feature known as servlet chaining, whereby one could essentially apply a list of filters to a servlet. Servlet filters are popular because they're useful for security, compression, logging, and more. And, of course, you can compose a chain of filters to do some or all of those things depending on runtime conditions.
With the advent of the Java Servlet Specification version 2.3, filters became standard components. Unlike classic CoR, servlet filters allow multiple objects (filters) in a chain to handle a request.
Servlet filters are a powerful addition to J2EE. Also, from a design patterns standpoint, they provide an interesting twist: If you want to modify the request or the response, you use the Decorator pattern in addition to CoR. Figure 3 shows how servlet filters work.
Figure 3. Servlet filters at runtime
A simple servlet filter
You must do three things to filter a servlet:
Implement a servlet
Implement a filter
Associate the filter and the servlet
Examples 1-3 perform all three steps in succession:
Example 1. A servlet
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.http.*;
public class FilteredServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {
PrintWriter out = response.getWriter();
out.println("Filtered Servlet invoked");
}
}
Example 2. A filter
import java.io.PrintWriter;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
public class AuditFilter implements Filter {
private ServletContext app = null;
public void init(FilterConfig config) {
app = config.getServletContext();
}
public void doFilter (ServletRequest request, ServletResponse response,
FilterChain chain) throws java.io.IOException,
javax.servlet.ServletException {
app.log(((HttpServletRequest)request).getServletPath());
chain.doFilter (request, response);
}
public void destroy() { }
}
Example 3. The deployment descriptor

PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/j2ee/dtds/web-app_2.3.dtd">


auditFilter
AuditFilter

< filter-mapping >
auditFilter
/filteredServlet
< /filter-mapping >


filteredServlet
FilteredServlet


filteredServlet
/filteredServlet

...

If you access the servlet with the URL /filteredServlet , the auditFilter gets a crack at the request before the servlet. AuditFilter.doFilter writes to the servlet container log file and calls chain.doFilter() to forward the request. Servlet filters are not required to call chain.doFilter() ; if they don't, the request is not forwarded. I can add more filters, which would be invoked in the order they are declared in the preceding XML file.
Now that you've seen a simple filter, let's look at another filter that modifies the HTTP response.
Filter the response with the Decorator pattern
Unlike the preceding filter, some servlet filters need to modify the HTTP request or response. Interestingly enough, that task involves the Decorator pattern. I discussed the Decorator pattern in two previous Java Design Patterns articles: " Amaze Your Developer Friends with Design Patterns " and " Decorate Your Java Code ."
Example 4 lists a filter that performs a simple search and replace in the body of the response. That filter decorates the servlet response and passes the decorator to the servlet. When the servlet finishes writing to the decorated response, the filter performs a search and replace within the response's content.
Example 4. A search and replace filter
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SearchAndReplaceFilter implements Filter {
private FilterConfig config;
public void init(FilterConfig config) {


 

Read Tutorial at: Click here to view the tutorial

Rate Tutorial:
good design pattern

View Tutorial:
good 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
 
Programming Java threads in the real world, Part 6 - JavaWorld - March 1999
Programming Java threads in the real world, Part 6 - JavaWorld - March 1999
 
Design networked applications in RMI using the Adapter design pattern
Design networked applications in RMI using the Adapter design pattern
 
An open alternative to JSP - The faults of JSP So what's wrong with JSP?
How the template-based, open source API FreeMarker trumps JSP
 
Become a programming Picasso with JHotDraw - JavaWorld February 2001
Become a programming Picasso with JHotDraw - JavaWorld February 2001
 
J2EE project dangers! - JavaWorld March 2001
J2EE project dangers! - JavaWorld March 2001
 
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
 
Big designs for small devices
Big designs for small devices
 
Simply Singleton
Simply Singleton
 
confusing title
confusing title
 
Create client-side user interfaces in HTML, Part 2
Create client-side user interfaces in HTML, Part 2
 
To my mind, of few interest
To my mind, of few interest
 
good design pattern
good design pattern
 
Java theory and practice: Kill bugs dead
Inspection tools like FindBugs provide a second layer of defense against common coding errors.
 
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
 
Building Java Server Pages
A detailed look at building JSP pages. Should you use JSP or servlets? It mainly depends on the ratio of markup to code. Here you'll also find a guide to the different varieties of tag, and details about the main tags such as and  
FreeMarker FreeMarker 2.3.1 an open-source HTML template engine.
FreeMarker provides an easy way to get data from Java servlets into Web pages, and helps you keep graphic design separate from application logic. To use it, you encapsulate HTML in templates.
 
JavaServer Pages Technology - Documentation
Sun's tutorial for Java Server Pages that provide a good introduction to design web pages with JSP.
 
Site navigation
 

 

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

Copyright © 2006. All rights reserved.