Brixen Decorators: What’s Changed

The basic concept of the decorators hasn’t changed. There are just more of them. I have added decorators for state beans, configuration beans and builders in addition to the decorators for the component implementations. The decorators help reduce boilerplate code by using a new feature introduced in Java 8: default interface methods. A class can implement numerous interfaces, but extend only one class. Prior to Java 8, this meant implementing the same methods over and over again in different classes extending a particular interface. After Java 8 however, a decorator interface can extend another interface and provide default method implementations for the interface it extends.

Here is an example of the PolleableBeanDecorator, which provides default method implementations for the methods required by PolleableBean:

The decorator defers all the PolleableBean method calls to the default PolleableBean implementation — PolleableBeanImpl. This is achieved by requiring a ‘provider’ for an internal reference to a PolleableBeanImpl instance. So any class which implements PolleableBeanDecorator needs to define an accessor method for this provider. Let’s have a look at the provider for a state bean:

I didn’t want to have a method in a decorator interface that would return a reference to the internal state bean itself because that would break encapsulation. So, I came up with the idea of a ‘provider’ which would give protected access to this internal state bean reference so that only a sub-class or a class within the same package as the provider would be able to access the internal state bean reference. The packaging structure I chose allows only the provider and its sub-classes, the decorator and other classes in their package to access the provider’s internal state bean reference.

Here is an example of a state bean which extends PolleableBeanDecorator:

DynamicControllableBean is a state bean for specifying a page object that contains one or more web controls which needs to be polled for state change of some kind, usually after an interaction with one of its controls. A drop down menu, for example, would need to be polled after interacting with the control that expands or collapses it to determine if the menu has expanded or collapsed as expected. The default implementation of DynamicControllableBean can only extend a single class, so its parent is ControllableBeanImpl.

It would be a drag to have to provide implementations for the methods required by PolleableBean which are exactly the same as the implementations provided in PolleableBeanImpl. By implementing the PolleableBeanDecorator interface, DynamicControllableBeanImpl can satisfy all the requirements of PolleableBean by providing only an accessor to a LoadableBeanProvider that wraps an instance of PolleableBeanImpl. Lombok helps reduce the amount of source code even more because the provider field only has to be annotated with the Getter annotation.

The decorators for the configuration beans operate in the same way. Here is the PolleableConfigDecorator and the provider for a configuration bean:

And here is DynamicControllableConfigImpl, a configuration bean which implements PolleableConfigDecorator:

Decorators for the builders was a bit trickier to pull off, but I managed to find a way. Here is the PolleableBuilderDecorator:

And AbstractDynamicControllableBuilder, which implements it:

This decorator implementation works by declaring a provider which wraps the builder implementing the decorator. The same state bean must encapsulate all the state for the component, so declaring a builder with a separate state bean instance wouldn’t work.

The decorators for the components haven’t changed, so I won’t post any examples here since it would just duplicate what I presented at the conference. The source code for Brixen is here.

Share This:


Leave a Reply

Your email address will not be published.