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

joi, 6 august 2015

JSF and Factory pattern - part I

Read also: JSF and Factory pattern (CDI aspects) - part II

The Factory pattern is commonly used to create objects via:

·         factory method pattern - defines a method that creates and return new objects
·         abstract factory pattern - delegates a subclass to create new objects

The main idea consist in the fact that the object is abstracted away from where it will be used!

Factory method pattern

Factory Method is a Creational Design Pattern with the following object structural:

The GoF (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) book describes this pattern as "An interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."

Let's suppose that we have the following objects (artifacts):

public interface Artifact {}

public class Artifact_A implements Artifact {
 public Artifact_A() {}
}

public class Artifact_B implements Artifact {
 public Artifact_B() {}
}

Further, we define an abstract class that will be extended later by the concrete implementations. Here we write the factory method signature - this method should be capable to return Artifacts:

public abstract class ArtifactFactory {
 public abstract Artifact getArtifact();
}

Next, we have two factory implementations:

public class ArtifactFactory_A extends ArtifactFactory {

 @Override
 public Artifact getArtifact() {
  return new Artifact_A();
 }  
}

public class ArtifactFactory_B extends ArtifactFactory {

 @Override
 public Artifact getArtifact() {
  return new Artifact_B();
 }   
}

Now,  some simple usages:

ArtifactFactory artifactFactory = new ArtifactFactory_A();
Artifact artifact = artifactFactory.getArtifact();
Artifact_A artifact_A = (Artifact_A)artifactFactory.getArtifact();

Abstract factory pattern

Abstract Method is a Creational Design Pattern with the following object structural:
The GoF (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) book describes this pattern as "Provides an interface for creating families of related or dependent objects without specifying their concrete classes."

The abstract factory pattern relies on factories that encapsulate groups of factories and control over how the client accesses them. Is beyond our aim to discuss this pattern.

JSF factory pattern implementation
JSF uses the factory method pattern for exposing a set of artifacts. We can point out some of them as: PartialViewContext, RenderKit, ExceptionHandler, VisitContext, ExternalContext, Flash, etc. These are abstract classes that belongs to JSF specification and have proper implementations in Mojarra/MyFaces of type ArtifactImpl. For each such artifact, JSF provides a factory class capable to create and return a new ArtifactImpl instance.

JSF specification provides the abstract factory classes that will be extended by the concrete implementations. The names of these classes follows the pattern ArtifactFactory, and the implementations (Mojarra and Apache MyFaces) follows the pattern ArtifactFactoryImpl.

For example, the ExceptionHandler artifact has the following abstract factory attached in the specification:

// JSF 2.0 specification
public abstract class ExceptionHandlerFactory implements FacesWrapper<ExceptionHandlerFactory> {

 public ExceptionHandlerFactory() {
 }
   
 public ExceptionHandlerFactory getWrapped() {
  return null;
 }

 public abstract ExceptionHandler getExceptionHandler();   
}

Now, the concrete implementations extends ExceptionHandlerFactory. For example, the Mojarra implementation is com.sun.faces.context.ExceptionHandlerFactoryImpl:

public class ExceptionHandlerFactoryImpl extends ExceptionHandlerFactory {

 public ExceptionHandlerFactoryImpl() {
 }

 public ExceptionHandler getExceptionHandler() {
  // return an ExceptionHandler implementation instance
 }
...
}

In Apache MyFaces we have the implementation available in

org.apache.myfaces.context.ExceptionHandlerFactoryImpl:

public class ExceptionHandlerFactoryImpl extends ExceptionHandlerFactory {
 @Override
 public ExceptionHandler getExceptionHandler() {
  // return an ExceptionHandler implementation instance
 }
}
In JSF, the factories are initialized by FactoryFinder, which recognizes if a custom factory has a delegating constructor—a one argument constructor for the type of the factory. JSF is very flexible, so we can write custom factories implementations to return custom artifacts and/or to alter an existing factory instance (see the factory getWrapper() method above).

This is useful when we want to wrap standard factory from JSF, because FactoryFinder will pass in the previously known factory, usually the built-in one. Factory instances are obtained as follows:

XXXFactory factory = (XXXFactory) FactoryFinder.getFactory(FactoryFinder.XXX_FACTORY);

For example, RenderKitFactory can be found using the following code:

RenderKitFactory factory = (RenderKitFactory) FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);

Commonly, when we need to instruct JSF to return a custom artifact provided via a factory, we follow three main steps:

1. Write the custom artifact (JSF provides wrappers for almost all artifacts, so, most probably you will extend the corresponding wrapper - of course, if you don't need the original artifact instance or you need to implement the entire set of artifact abstract methods, then you don't need the wrapper class).
2. Write the factory implementation by extending the ArtifactFactory class and overriding the desired methods (obviously, among others, we need here the method capable to return the artifact instances).
3.Instruct JSF to use our factory implementation by making the required configurations in faces-config.xml via the <factory> tag.

You can see an example of writing a custom RenderKitFactory in Write Custom RenderKitFactory Skeleton. More examples are available in chapter 5 of book, Mastering JavaServer Faces 2.2.

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors