Read also:
In this
part, we try to indentify a real use case of the composite design pattern
inside JSF source code. Remember that the composite pattern work with composite and leaf (primitive) objects that should be treated equally
(uniformly), and a composite object is a container for leaf (primitive) objects.
Keeping this in mind, we can start diving in JSF source code in order to
identify the base component object, the leaf objects and the composite objects.
As a JSF
developer, you should know the importance of the view (UI view) in JSF
lifecycle, and you should know that the view is build in the first phase,
Restore View Phase, and in the last phase, Render Response phase. The view is
basically the JSF unit of work and it contains JSF UI components. All JSF UI
components have a super-component known as UIComponentBase (extends
Component)
which represents an abstract base
component in composite pattern. Basically, the UIComponentBase provides a
set of common methods for JSF UI components, such as methods for decoding (e.g.
decode(),processDecodes()),
encoding (e.g. encodeBegin(),
encodeChildren(),
encodeEnd()),
subscribe to events (e.g. subscribeToEvent()), etc.
base
component in composite pattern
// javax.faces.component.UIComponentBase
public
abstract class UIComponentBase extends UIComponent {
// methods for UI components
public void decode(FacesContext context) {
...
}
public void encodeBegin(FacesContext context)
throws IOException {
...
}
public void processDecodes(FacesContext
context) {
...
}
...
}
So, the JSF
UI components extends and shapes the UIComponentBase contract. Components
like, UIInput,
UIOutput,
UIPanel,
UISelectMany,
UISelectOne,
UIForm,
etc, extend the UIComponentBase
and override the necessary methods. This means that we can easily intuit that
these components are actually the leaf
(primitive) objects in the composite pattern, and the base component (UIComponentBase) defines common methods for leaf objects (UI components) and composite
objects.
Leaf
object in composite pattern
// javax.faces.component.UIOutput
// javax.faces.component.UIOutput
public class
UIOutput extends
UIComponentBase implements ValueHolder {
...
}
Leaf
object in composite pattern
// javax.faces.component.UIPanel
// javax.faces.component.UIPanel
public class
UIPanel extends
UIComponentBase {
...
}
Further, we
have to identify the composite
object. Theoretically speaking, this object should "hold" together
the leaf objects (UI components) and
implements the operations in base
component (UIComponentBase).
Since the JSF UI components are "grouped" in a view, we can say that
the view represents the composite
object, which programmatically is represented by the UIViewRoot component:
composite
objects in composite pattern
// javax.faces.component.UIViewRoot
// javax.faces.component.UIViewRoot
public class
UIViewRoot extends
UIComponentBase implements UniqueIdVendor {
...
}
So, we have
identified the following JSF artifacts as the composite pattern implementation:
·
base
component object - UIComponentBase
·
leaf
(primitive) objects - UI components (e.g. UIOutput, UIPanel,
UIForm,
etc)
·
composite
object - UIViewRoot
(JSF view)
Niciun comentariu :
Trimiteți un comentariu