See: Description
Interface | Description |
---|---|
Faceted |
Provides access to optional extension interfaces of a subject instance.
|
Class | Description |
---|---|
Facets |
Utility methods for working with facets.
|
Exception | Description |
---|---|
UnsupportedFacetException |
Indicates a failed request to find a required facet of
some subject.
|
A facet is an interface representing optional functionality that may be supported by one or more subject types. By itself, the facet looks no different than any other interface. What's different is how instances of the facet are acquired from the subjects that support it.
Traditionally, a class supports optional functionality via subtypes, and
the user typically performs an instanceof
operation before
downcasting to the optional type.
This works well for simple designs, but it runs into problems when combined
with design patterns like Decorator or Adaptor.
For example, a Decorator provides only modified functionality and can't be
responsible for implementing all possible extensions.
The Facet pattern resolves this problem by allowing the implementation of the facet to be separate from the subject instance. A Decorator can choose to "pass-through" facets of the decorated subject, without implementing the functionality itself. This also allows different instances of the subject to support different sets of facets, based on its particular state.
The central focus of the pattern is the
Faceted.asFacet(Class)
method.
Subjects that wish to support facets implement it to allow users to request
the desired facet.
This method returns null when the subject doesn't support the facet.
The asFacet()
method is used as a replacement
for the traditional instanceof
/typecast idiom. The subject is in
control of the result, and can do any number of things more sophisticated
than simply downcasting itself to the facet type.
Given a concrete Faceted
class, it may be that
some instances support a particular facet while others do not, depending on
the state of the subject or the way it was constructed. In such cases
asFacet
should choose whether
to return the facet based on the subject's state.
Such classes should not extend the facet interface (directly or
indirectly), since that allows clients to bypass asfacet
and
simply downcast the subject to the facet,
causing problems for instances that can't support the facet.
locale
facets.