My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

vineri, 2 octombrie 2015

JSF and Template Method design pattern - part I (plain code)

Template Method is a Behavioral Design Pattern with the following object structural:
The GoF (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) book describes this pattern as a pattern that "Defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Template Method lets subclasses redefine certain steps of an algorithm without changing the algorithms structure."
Typically a problem that fits the template method design pattern consist in a complex task that can be accomplished by breaking it into several preset steps. An abstract class contains a stub method for establishing the order of executing these steps. Some of these steps are implemented in this abstract class (default implementation that is common to all subclass), while the rest of steps are implemented by subclasses (custom implementation that is specific to each subclass).

For example, let suppose that we have a printer service. Basically, we need to set the printer before each print, and in order to accomplish that we need to:

- check printer ink (default implementation)
- check cartridges (default implementation)
- feed printer with paper (custom implementation, different paper sizes)
- align printing margins (custom implementation, different margins depending on paper size)
- print style (custom implementation, color and grayscale)

The above actions need to take place in this preset order and some of them (check print ink and cartridges) are common actions, while others are specific actions. For keeping this order, we need a final stub method that basically represents the main action - printing. Since is final, subclasses cannot alter the step order.

So, first we need to write the abstract class that contains the stub method and the default/custom implementations - notice that we marked the default implementations as private because we don't want them to be callable/modifiable from subclasses, but this is not mandatory!

public abstract class PrinterTemplate {

 //template method, final so subclasses can't override
 public final void print(){
  checkInkLevel();
  checkCartridges();
  feedWithPaper();
  alignMargins();
  printStyle();
 }
   
 // default implementation
 private void checkInkLevel() {
  System.out.println("The printer ink level have been check!");
 }

 // default implementation
 private void checkCartridges() {
  System.out.println("The printer cartridges have been check!");
 }

 //methods to be implemented by subclasses
 public abstract void feedWithPaper();
 public abstract void alignMargins();
 public abstract void printStyle();       
}

Next, we provide the template method concrete classes. We have A4Printing and A1Printing, as follows:

public class A4Printing extends PrinterTemplate {

 @Override
 public void feedWithPaper() {
  System.out.println("Feed with paper A4 format.");
 }

 @Override
 public void alignMargins() {
  System.out.println("A4 margins: top/1.0in, bottom/0.75in, left/0.75in, right/0.75in.");
 }

 @Override
 public void printStyle() {
  System.out.println("A4 print in colors.");
 }  
}

public class A1Printing extends PrinterTemplate {

 @Override
 public void feedWithPaper() {
  System.out.println("Feed with paper A1 format.");
 }

 @Override
 public void alignMargins() {
  System.out.println("A1 margins top/0.5in, bottom/0.5in, left/0.2in, right/0.2in.");
 }

 @Override
 public void printStyle() {
  System.out.println("A1 print in grayscale.");
 } 
}

Finally, we can perform a test:

PrinterTemplate printerA1 = new A1Printing();
printerA1.print();

PrinterTemplate printerA4 = new A4Printing();
printerA4.print();

The output will be:

The printer ink level have been check!
The printer cartridges have been check!
Feed with paper A1 format.
A1 margins top/0.5in, bottom/0.5in, left/0.2in, right/0.2in.
A1 print in grayscale.

The printer ink level have been check!
The printer cartridges have been check!
Feed with paper A4 format.
A4 margins: top/1.0in, bottom/0.75in, left/0.75in, right/0.75in.
A4 print in colors.

In template pattern, super-class template method calls methods from subclasses, this is known as Hollywood Principle – "don’t call us,we’ll call you".

In the next part we will re-write this example in JSF+CDI style.

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

OmniFaces/JSF Fans

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors