Skip to content

11. Built in decorator pattern

Jim Riordan edited this page Aug 10, 2016 · 1 revision

###Built-in decorator pattern

Yadic lets you decorate objects that are already in a container to extend their functionality without modifying their source code (Open/closed principle). In other words Yadic uses a decorator pattern. Let's take a look at the following example:

container.add(HttpHandler.class, BaseHandler.class); 
container.add(Auditor.class); // required by the AuditHandler 
container.decorate(HttpHandler.class, AuditHandler.class);

... 

public interface HttpHandler {
    Response handle(final Request request) throws Exception;
} 

public class BaseHandler implements HttpHandler { 
    // basic HTTP handling functionality 
} 

public class AuditHandler implements HttpHandler {
    private final HttpHandler delegate;
    private final Auditor auditor;

    public AuditHandler(HttpHandler delegate, Auditor auditor) {
        this.delegate = delegate;
        this.auditor = auditor;
    }

    public Response handle(Request request) throws Exception {

        Date requestDate = new Date();
        Response response = delegate.handle(request);
        Date responseDate = new Date();
        try {
            auditor.audit(pair(request, requestDate), pair(response, responseDate));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }
}

In the example above we enhanced base HTTPHandler by adding auditing capability in a decorator. Every time we request an HttpHandler from a container we'll get an AuditHandler which is a wrapper around the original BaseHandler.

System.out.println(container.get(HttpHandler.class) instanceof AuditHandler); // true 

Obviously, we can decorate our HttpHandler many times:

container.decorate(HttpHandler.class, BasePathHandler.class); 
container.decorate(HttpHandler.class, ExceptionHandler.class); 
container.decorate(HttpHandler.class, ContentLengthHandler.class); 
container.decorate(HttpHandler.class, AuditHandler.class); ... ```

Clone this wiki locally