Java Reference
In-Depth Information
You must add the decorators to the bean.xml archive in the order that you want them to be invoked.
Here, you declare that the PriceDiscountDecorator decorator should be invoked before the
BlackFridayDiscountDecorator decorator.
<decorators>
<class>com.devchronicles.decorator.PriceDiscountDecorator</class>
<class> com.devchronicles.decorator.BlackFridayDiscountDecorator </class>
</decorators>
When the generateLabel method is invoked, a call chain is set up that includes the two
decorators. The call to generateLabel is intercepted and delegated to the generateLabel method
of the PriceDiscountDecorator . It calls r getPrice , which will be intercepted and delegated to
the getPrice method of BlackFridayDiscountDecorator, which in turn calls the getPrice
method of its injected Product object. (This is the same instance that you injected into the
PriceDiscountDecorator decorator.) This invocation is not intercepted because there are no
more decorators declared for this interface, and it calls the getPrice method in the Table object.
Once this call has i nished, it returns down the call stack to the i rst getPrice method. This is
called returning the price of the Table . The decorator reduces the price by 50 percent and calls the
setPrice method. This call is delegated up the call chain until it reaches the Table object, where the
new price is set. Then the call returns down the call chain.
The getLabel method is called and creates a call chain similar to that of the getPrice method.
Finally, the generateLabel method is invoked and intercepted by the
BlackFridayDiscountDecorator decorator. The price is discounted by a further 25 percent, and a
call chain similar to that set up by the PriceDiscountDecorator decorator is initiated.
The output to the console follows:
Label: 6.25, Dining Table (Discounted)
For the chain to continue unbroken, the generateLabel method must delegate to the
generateLabel method of the delegate injected instance; otherwise, the chain is broken and only
the i rst decorator is invoked.
All classes that implement the same interface as the one implemented by the delegate injection
point are decorated, but only if those decorators are declared in bean.xml . This has two major
implications:
Decorators can be enabled and disabled at deployment time by editing the bean.xml i le.
This gives great l exibility over when and which decorators are invoked. For example, you
can implement a price discount decorator only for the duration of the sales period and
disable it when the period comes to an end. The l exibility of the deployment descriptor
declaration means that this decorator can be easily enabled again if debugging information is
later required.
A decorator is automatically applied to classes that implement the same interface. This is
efi cient at the time of adding new classes because they are decorated with no additional
coding. However, this could prove inconvenient if there is a requirement that not all classes
of the same type are decorated. Luckily, there is a solution to this situation that involves
using qualii ers to annotate only those classes that should be decorated.
Search WWH ::




Custom Search