Design pattern – Adapter or Wrapper

What is it?

Real world

  • Use a your camera memory card in your laptop
    • You cannot use it directly simply because there is no port in laptop which accept it
    • You must use a compatible card reader
    • You put your memory card into card reader and then inject card reader into laptop
    • This card reader can be called adapter
  • Adapter pattern enables two incompatible interfaces to work smoothly with each other
    • Convert the interface of a class into another interface clients expect
    • Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces

Sequence diagram

Coding example

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

System.out.print("Enter String");
String s = br.readLine();
System.out.print("Enter input: " + s);
  • System.in provides byte stream
  • BufferedReader expects character stream
  • How they will work together?
    • Put a adapter in between two incompatible interfaces
    • InputStreamReader does exactly this thing and works adapter between System.in and BufferedReader

Participants

  • Target (BufferedReader): It defines the application-specific interface that Client uses directly
  • Adapter (InputStreamReader): It adapts the interface Adaptee to the Target interface. It’s middle man
  • Adaptee (System.in): It defines an existing incompatible interface that needs adapting before using in application
  • Client: It is your application that works with Target interface

How much work the Adapter Pattern should do?

it should do only that much work so that both incompatible interfaces can adapt each other and that’s it

  • A InputStreamReader simply wraps the InputStream and nothing else
  • Then, BufferedReader is capable of using underlying Reader to read the characters in stream
/**
 * Creates an InputStreamReader that uses the default charset.
 * @param  in   An InputStream
 */
public InputStreamReader(InputStream in) {
    super(in);
    try {
        sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
    } catch (UnsupportedEncodingException e) {
        // The default encoding should always be available
        throw new Error(e);
    }
}

Other samples

java.util.Arrays#asList()

This method accepts multiple strings and return a list of input strings

java.io.OutputStreamWriter(OutputStream)

It’s similar to above usecase we discussed in this post:

Writer writer = new OutputStreamWriter(new FileOutputStream("c:\\data\\output.txt"));
writer.write("Hello World");

javax.xml.bind.annotation.adapters.XmlAdapter#marshal() and #unmarshal()

Adapts a Java type for custom marshaling. Convert a bound type to a value type.

Be the first to comment

Leave a Reply

Your email address will not be published.


*