Page 1 of 1

J'Accuse: InterceptingFilter

Posted: Wed Oct 13, 2004 1:13 pm
by McGruff
A description of InterceptingFilter might go something like this:

The InterceptingFilter pattern is used to wrap an application core with various pre and post processing tasks eg authentication, validation, logging, user input filters or output compression. Filters are loosely coupled allowing individual items to be added and removed at will. Filters don’t interact directly with the application core.

InterceptingFilter provides a central location for common tasks. Configuration files may be used to load different filter chains for different requests.

Different sets of filters might allow the same core to be re-used in a different context (perhaps this applies more to languages other than php).


Intuitively, you might think of a filter as something which silently processes a request, adjusting the values of certain parameters. For example, a magic quotes filter would check if magic quotes are on, and remove them if so.

However, InterceptingFilter is also used to load filters which don’t do any filtering in the dictionary sense of the word - authentication for example. An authentication filter might affect the logical flow of the program by making a decision on whether to continue processing the request or to stop and show a login page. The big difference compared to the magic quotes example is that authentication can direct request processing. This is what you might call a "request handling" role: ie deciding the nature of the response which should be made to an http request.

The charge against InterceptingFilter is that allowing request handling functionality in candidate filters is a major design flaw. Ideally you would have a single location where all the request handling is carried out but InterceptingFilter creates another layer where this can occur in addition to a FrontController/PageControllers. That can't be good.

A Chain of Responsibility is a good fit for request handling classes, however. By allowing items to be dropped in and out easily without disturbing anything else, it's a powerful pattern. Loosely coupled handlers create a robust, flexible design. Configurable chains can be customised per request at the same time as allowing common handlers to be shared.

We want to keep all that. Perhaps the answer is a separate request handling chain. This would be a strict GoF CoR (only one handler in the chain is ever active) and might look something like this (handler/client page):

validation handler/400-type page -->
authentication handler/login page -->
authorisation handler/access denied page -->
foo handler/the foo page -->
unknown resource/404.

Requests would map one to one with handler chains and individual handlers would map one to one with one of the possible client pages which might be generated as part of the response to a request. A handler chain which maps to a form submission might add a redisplay handler and a form processor handler to the above list.

If request-handling is refactored into its own chain, InterceptingFilter no longer does any intercepting. We could simply call it a FilterChain - except that filter candidates don't necessarily do any filtering either (logging is often mentioned as a candidate filter, for example). In essence, InterceptingFilter is just a frame on which to hang any kind of tasks which wrap the core. Some don’t intercept. Some don’t filter. Some might not do either. So let's rename it CoreWrapper.

Perhaps it should be deconstructed further although a certain degree of vagueness could be useful in a layer which can serve as a kind of catch-all for items you didn't think about when you first wrote the app. I'm really not sure: the main thing is to get all the request handling out of there.