The Decorator Pattern

The Decorator Pattern

decoratingOne design pattern that I don’t see being used very often is Decorator. I’m not sure why this pattern isn’t more popular, as it’s quite handy. The Decorator pattern allows one to add functionality to an object in a controlled manner. This works at runtime, even with statically typed languages! The decorator pattern is an alternative to subclassing. Subclassing adds behavior at compile time, and the change affects all instances of the original class; decorating can provide new behavior at run-time for individual objects. The Decorator pattern is a good tool for adhering to the open/closed principle.

Some examples may show the value of this pattern:

Example 1: HTTP Authentication

Imagine an HTTP client, for example one that talks to a RESTful service.

Some parts of the service are publicly accessible, but some require the user to log in. The RESTful service responds with a 401 Unauthorized status code when the client tries to access a protected resource.

Changing the client to handle the 401 leads to duplication, since every call could potentially require authentication. So we should extract the authentication code into one place. Where would that place be, though?

Here’s where the Decorator pattern comes in:

public class AuthenticatingHttpClient
    implements HttpClient {

  private final HttpClient wrapped;

  public AuthenticatingHttpClient(HttpClient wrapped) {
    this.wrapped = wrapped;
  }

  @Override
  public Response execute(Request request) {
    Response response = wrapped.execute(request);
    if (response.getStatusCode() == 401) {
      authenticate();
      response = wrapped.execute(request);
    }
    return response;
  }

  protected void authenticate() {
    // ...
  }

}

A REST client now never has to worry about authentication, since the AuthenticatingHttpClient handles that.

Example 2: Caching Authorization Decisions

OK, so the user has logged in, and the REST server knows her identity. It may decide to allow access to a certain resource to one person, but not to another.

IOW, it may implement authorization, perhaps using XACML. In that case, a Policy Decision Point (PDP) is responsible for deciding on access requests.

Checking permissions it often expensive, especially when the permissions become more fine-grained and the access policies more complex. Since access policies usually don’t change very often, this is a perfect candidate for caching.

This is another instance where the Decorator pattern may come in handy:

public class CachingPdp implements Pdp {

  private final Pdp wrapped;

  public CachingPdp(Pdp wrapped) {
    this.wrapped = wrapped;
  }

  @Override
  public ResponseContext decide(
      RequestContext request) {
    ResponseContext response = getCached(request);
    if (response == null) {
      response = wrapped.decide(request);
      cache(request, response);
    }
    return response;
  }

  protected ResponseContext getCached(
      RequestContext request) {
    // ...
  }

  protected void cache(RequestContext request, 
      ResponseContext response) {
    // ...
  }

}

As you can see, the code is very similar to the first example, which is why we call this a pattern.

As you may have guessed from these two examples, the Decorator pattern is really useful for implementing cross-cutting concerns, like the security features of authentication, authorization, and auditing, but that’s certainly not the only place where it shines.

If you look carefully, I’m sure you’ll be able to spot many more opportunities for putting this pattern to work.
 

Reference: The Decorator Pattern from our JCG partner Remon Sinnema at the Secure Software Development blog.
Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

5 Responses to "The Decorator Pattern"

  1. Joseph says:

    Hello Remon, I like this pattern and you explain it very well, I have only 1 complain: I think class names should be pronouns like –> HTTPClientAuthenticator and PDPCacheResolver (?) or PDPCacher (?) or PDPCacheWorker even PDPCacheDecorator so the people who has knowledge about the pattern will notice it instantly :).

    • Hi Joseph,

      Thanks for reading an commenting.

      I’m no linguist, but it seems to me that CachingPdp consists of an adjective and a noun. I agree that there should be a noun in there (not a pronoun). An adjective “serves as a modifier of a noun to denote a quality of the thing named, to indicate its quantity or extent, or to specify a thing as distinct from something else ” (http://www.merriam-webster.com/dictionary/adjective), which seems highly appropriate to me.

      I don’t like PDPCacheDecorator, since it’s a technical name that focuses on the how rather than the what.

      • Joseph says:

        Remon, my bad about pronouns (that was a blackout) Yes, I mean nouns. You are right about PDPCacheDecorator that’s why I say “even”, it’s of course the last resort (I wouldn’t use it personally) but what I’m trying to point here is CachingPDP sounds (to me) more like a method than a class, PDPCacheResolver would be a class name I expect for a class that issue the process of PDP cache.

  2. sermyro says:

    Hello Remon, the decorator pattern is used a lot with streams: for example, Java I/O classes

    • Yes. This allows you to do something like:
      new BufferedReader(new InputStreamReader(new FileInputStream(new File(path))))
      where you keep adding functionality by decorating objects. This keeps the individual decorator classes small and focused, reducing the chance of bugs.

Leave a Reply


2 + one =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books