Adapter design pattern talks about Convert
the existing interfaces to a new interface to achieve compatibility and re usability of the unrelated classes in one application also known as Wrapper pattern
“A class converts the interface of one class to be what another
class expects.”
In real world we have adapters for power supplies,
adapters for camera memory cards, and so on.
The Adapter pattern is used so that two unrelated
interfaces can work together. The joining between them is called an Adapter.
This is something like we convert interface of one class into interface
expected by the client. We do that using an Adapter.
An adapter allows classes to work together that
normally could not because of incompatible interfaces, by providing its
interface to clients while using the original interface
It comprises three components:
- Target: This is the interface with which the client interacts.
- Adaptee: This is the interface the client wants to interact with, but can’t interact without the help of the Adapter.
- Adapter: This is derived from Target and contains the object of Adaptee.
There
are 2 ways to implement Adapter 1) Inheritance 2) Composition
1) Inheritance: Class Adapters - Based on (Multiple) Inheritance
In the language supporting inheritance we can use this.
here we can extends the Adaptee . The adapter class which is inherited will
have new compatible methods. Using those new methods from the adapter the core
function of the base class will be accessed. This is called “is-a”
relationship.
- It adapts the specific Adaptee class. The class it extends. If that one is subclassed it can not be adapted by the existing adapter.
- It doesn't require all the code required for delegation, which must be written for an Object Adapter.
1: public class CylindricalSocket {
2: public String supply(String cylinStem1, String cylinStem1) {
3: System.out.println("Power power power...");
4: return "I got power";
5: }
6: }
1: public class RectangularAdapter extends CylindricalSocket {
2: public String adapt(String rectaStem1, Sting rectaStem2) {
3: //some conversion logic
4: String cylinStem1 = rectaStem1;
5: String cylinStem2 = rectaStem2;
6: return supply(cylinStem1, cylinStem2);
7: }
8: }
1: public class RectangularPlug {
2: private String rectaStem1;
3: private String rectaStem2;
4: public getPower() {
5: RectangulrAdapter adapter = new RectangulrAdapter();
6: String power = adapter.adapt(rectaStem1, rectaStem2);
7: System.out.println(power);
8: }
9: }
This type of adapter uses multiple polymorphic interfaces to achieve its goal.
The adapter is created by implementing or inheriting both the interface that is
expected and the interface that is pre-existing. It is typical for the expected
interface to be created as a pure interface class, especially in languages such as Java that do not support multiple inheritance
2) Composition (Objects Adapters - Based on Delegation)
: Instead of inheriting the base class create
adapter by having the base class as attribute inside the adapter. You can
access all the methods by having it as an attribute. This is nothing but “has-a” relationship. Following example
illustrates this approach. Difference is only in the adapter class and other
two classes are same. In most scenarios, prefer composition over inheritance.
Using composition you can change the behavior of class easily if needed. It
enables the usage of tools like dependency injection.
Objects Adapters are
the classical example of the adapter pattern. This behavior gives us a few
advantages over the class adapters
The main disadvantage is that it requires to write all the code for
delegating all the necessary requests tot the Adaptee.
In this type of adapter pattern, the adapter contains an instance of
the class it wraps. In this situation, the adapter makes calls to the instance
of the wrapped object.
1: public class CylindricalSocket {
2: public String supply(String cylinStem1, String cylinStem1) {
3: System.out.println("Power power power...");
4: }
5: }
1: public class RectangularAdapter {
2: private CylindricalSocket socket;
3: public String adapt(String rectaStem1, Sting rectaStem2) {
4: //some conversion logic
5: socket = new CylindricalSocket();
6: String cylinStem1 = rectaStem1;
7: String cylinStem2 = rectaStem2;
8: return socket.supply(cylinStem1, cylinStem2);
9: }
10: }
Adapter design pattern in java API
java.io.InputStreamReader(InputStream)java.io.OutputStreamWriter(OutputStream)
Notes :
1) Adapter Pattern and Strategy Pattern - there are many cases when the
adapter can play the role of the Strategy Pattern. If we have several modules
implementing the same functionality and we wrote adapters for them, the
adapters are implementing the same interface. We can simply replace the
adapters objects at run time because they implements the same interface.
2) Adapter makes things work after they're designed; Bridge makes them
work before they are.
3) Bridge is designed up-front to let the abstraction and the
implementation vary independently. Adapter is retrofitted to make unrelated
classes work together.
4) Adapter provides a different interface to its subject. Proxy provides
the same interface. Decorator provides an enhanced interface.
5) Facade defines a new interface, whereas Adapter reuses an old
interface. Remember that Adapter makes two existing interfaces work together as
opposed to defining an entirely new one.
6) Adapter is meant to change the interface of an existing object.
Decorator enhances another object without changing its interface. Decorator is
thus more transparent to the application than an adapter is. As a consequence,
Decorator supports recursive composition, which isn't possible with pure
Adapters.
No comments:
Post a Comment