GoF Adapter Pattern
Convert the interface of a class into another interface clients expect.
Adapter lets classes work together that couldn't otherwise because of incompatible
interfaces.
Componentized Adapter Pattern
PerfectJPattern's componentized version of the Adapter Pattern provides the following advantages:
- Automatic adaptation: PerfectJPattern's Adapter
implementation minimizes or even lowers to zero the amount of work needed to adapt a given Adaptee
implementation to a Target interface. These are the possible scenarios when adapting an arbitrary
Adaptee to a Target interface:
- Target interface is an exact subset of the Adaptee implementation with perfect match of method
names and signatures then the adaptation is done automatically i.e. just using
Adapter
- Target interface is a subset of the Adaptee with slight differences in method name or type (static
or instance) then the adaptation is done automatically i.e. just using
Adapter
.
- Adaptee implementation requires parameter conversion to match the Target interface then you need
to extend
Adapter
and provide implementation for only those methods requiring
the conversion
- Adaptee implementation requires different behavior or additional methods to match the
Target interface then you need to extend
Adapter
and provide implementation
for only those methods requiring the different behavior or implement the extra methods, see Example below
- Pluggable adaptation strategy: PerfectJPattern's Adapter implementation features configurable
strategies to adapt Target interfaces to Adaptee implementations. The current implementation offers two
concrete strategies:
- ExactMatchAdaptingStrategy: Validates and resolves Target methods looking for
exact matches in Adapter and Adaptee method names and signatures. This is the default strategy.
- NameMatchAdaptingStrategy: Uses user-defined mapping of Adaptee method names to Target
interface method names. Unspecified method names will default to the ExactMatchAdaptingStrategy
implementation.
PerfectJPattern's Adapter implementation offers a good trade-off between flexibility and strong compiler
checking. The advanced reuse and flexibility heavily increases productivity by cutting development time
at the cost of shifting to Runtime some of the issues that would otherwise be detected by the compiler.
The compromise is because the Adapter will do its best to match the Adaptee implementation to the Target
interface, but e.g. changes in the Adaptee method signatures could lead to Runtime precondition violations
while constructing the Adapter.
Technically speaking PerfectJPattern's Adapter implementation is type-safe, you will never get a Runtime
error due to a data type mismatch operation while using PerfectJPattern API i.e. you will never get a
ClassCastException. If you
do then it is a bug and will need to be fixed. Note that while the possible error has been shifted from Compiler to
Runtime, technically speaking this is not type-unsafe. What happens is that PerfectJPattern's implementation will
detect the erroneous situation at the framework level and translate it into a precondition violation at the API
level using e.g.
IllegalArgumentException. Precondition violations are to be discovered at testing time by having adequate
test coverage in place.
UML Class Design
Example