façade pattern

Before we deep into Facade Pattern, let’s see an example (it is descirbed in http://luohuahuang.com/2013/08/15/a-simple-servlet-container-in-java/) in the following,

facade

Here, the UML logic is very frank. Class HttpRequest implements interface javax.servlet.ServletRequest. Besides that, it also has two additional methods parse() and parseUri(String). ServletProcessor will use HttpRequest to handle Servlet affairs.

For a better understanding, let’s see below snippet,

// here request is a Class HttpRequest. It is converted into a Servlet class upwards.

Servlet servlet = null;

try {
 servlet = (Servlet) myClass.newInstance();
 servlet.service((ServletRequest) request, (ServletResponse) response);
 }

It smells bad because of below two points,

1. Both of parse() and parseUri methods should be unavailable from Servlet engine as they are internal use only. However in above code, both of the methods are accessible by Servlet.service through servlet.service((ServletRequest) request. That is vulnerable.

2. HttpRequest is a customized Class with new method, although it implements from javax.servlet.ServletRequest. Hence developers who have to develop Servlet services have to understand the details of HttpRequest. This effort is unnecessary as to develop Servlet services, all they need to know should be only strictly those methods from ServletRequest.

So, we need to find another way to hide the implementation of HttpRequest from Servlet.

Let’s Facade Pattern, http://en.wikipedia.org/wiki/Facade_pattern

Facade
The facade class abstracts Packages 1, 2, and 3 from the rest of the application.
Clients
The objects are using the Facade Pattern to access resources from the Packages.

 Similarly, the solution for HttpRequest is,

Create a Facade class which should implement the same as HttpRequest from javax.servlet.ServletRequest but without parse() or parseUri(String) method.

In the main method, change

from –


Servlet servlet = null;

try {
 servlet = (Servlet) myClass.newInstance();
 servlet.service((ServletRequest) request, (ServletResponse) response);
 }

to –

Servlet servlet = null;
 RequestFacade requestFacade = new RequestFacade(request);
 ResponseFacade responseFacade = new ResponseFacade(response);
 try {
 servlet = (Servlet) myClass.newInstance();
 servlet.service((ServletRequest) requestFacade, (ServletResponse) responseFacade);
 }

In this way, we can hide parse() and parseUri(String), and make the interface of HttpRequest more clear and tidy.

You can see more from source code of org.apache.catalina.connector