Wednesday 11 April 2007

Interceptor Design Pattern

Usage of Interceptor Design Pattern [POSA2] can solve many problems in daily development. It is very easy to:

  • monitor what is the application doing inside
  • provide possibility to change some of application's behavior
  • provide possibility to extend application with new features
    • implementer of the extension need not to know rest of the application
    • implementer of the extension need not change existing code
    • new extensions can or can not affect current system
Interceptor design pattern is built from three basic components:
  1. IInterceptor interface
  2. Dispatcher
  3. Context

IInterceptor - IInterceptor interface can define arbitrary number of operations which are executed by Dispatcher in specific cases (at the beginning of the request processing or at the end of the request processing). There is typically just one parameter for every method - Context - carrying input and output data. The interface is then implemented by specific interceptors (logging, authorization, transaction, ...).

Dispatcher - Dispatcher class typically implements IInterceptor interface. There are many ways how the dispatching can be implemented. For example the interceptors called by Dispatcher can be prioritized or exception thrown from interceptor can be handled as interception termination. The Dispatcher is the class which is called from "intercepting point" to perform intercepting.

Context - Context is typically simple data object used to carry data for interceptors or to keep results of intercepting (eg. transaction id generated by TransactionInterceptor). There can be different Context implementations not only for different IInterceptor interfaces but also for different methods of IInterceptor interface.


As mentioned in description of basic elements the Interceptor pattern has many degree of freedom:
  1. IInterceptor
    • one/many methods
    • one/many Context types for many methods
    • result propagation to Dispatcher, intercepting point or following interceptors
      • Context - Dispatcher can decide about next step by status of the Context
      • Exception - Dispatcher can handle different exceptions different way
  2. Dispatcher
    • implements/does not implement IInterceptor interface
    • dispatching mechanism (prioritized, random, based on context, ...)
Implementation of Interceptor Pattern is not the easiest work. But whenever it is implemented it is very simple to extend application by new features or change its behavior.

Related patterns:
  • Template Method [GoF]
    • Very simple version of Interceptor Pattern implementing Dispatcher (template method) and IInterceptor implementations (methods called from template method) in one class.
  • Chain of Responsibility [GoF]
    • Does not have Dispatcher - the order of "interceptors" is defined as chain of successors.
  • Intercepting Filter
    • Similar also to Chain of Responsibility but the chain of successors is not "hard coded" but propagated to "interceptor" as parameter of the method call.

References:

AddThis Feed Button 2 comments:

Unknown said...

Very well prepared with the diagrams and so on, almost like a short book article.
I'd love to find a single pattern explained within my subscriptions each week. This would be a nice reminder.. =)

rebk22 said...

wonderfull explain, now i understand... thanks