Wednesday, July 9, 2014

Adapter Design Pattern

INTRODUCTION

When we enter into a new country and we don't know the language which they speak, it is very tough to get the things done there, so we will look for any mediator or the communicator who can understand both our language and their language.
The communicator or the mediator also called as Adapter who makes our life easier. In the programming way, the Adapter helps the caller to get the things done from the callee when both are different in nature.
So basically, the Adapter design pattern may come into picture when two or more unrelated interface should work together in an application.

USECASE

Consider I have an old application which will read the .txt & .pdf file format alone and it won't accept other file formats. My calling code sends the file and reads the content of the file.

IMPLEMENTATION

Lets us create a FileReader Interface which will have necessary methods to read a file and get the content.

public interface FileReader {  
 void readFile(String fileType);  
}

Write the implementation for the above interface.

public class MyFileReader implements FileReader {

 public void readFile(String fileType) {
   System.out.println("File Type is: "+ fileType);

   if (fileType.equalsIgnoreCase(".txt")
       || fileType.equalsIgnoreCase(".pdf")){
     System.out.println("Reading the file format : " + fileType);
   } else {
     System.out.println("ERROR..Invalid File Format, Couldn't Read!!!");
   }
 }
}

When we call MyFileReader and pass the input .txt and .docx, we will get the output as below.

Create a client.
public class AdapterPatternTest {
 public static void main(String[] args) {

   FileReader fileReader = new MyFileReader();
   fileReader.readFile(".txt");

   System.out.println("\n");
   fileReader.readFile(".pdf");

   System.out.println("\n");
   fileReader.readFile(".docx");
 }
}

OUTPUT


File Type is: .txt
Reading the file format : .txt


File Type is: .pdf
Reading the file format : .pdf


File Type is: .docx
ERROR..Invalid File Format, Couldn't Read!!!

Now we have got new requirements to read the other format like .docx, .xlsx and I don't want to change my calling code.

No need to worry here, we have got Adapter design pattern.
Adapter design pattern can be implemented in two ways.
1. Using Inheritance
2. Using Composition

IMPLEMENTATION - USING INHERITANCE

The below Adapter can help to read the .docx,.xslx format files without changing the calling code with the help of AdvancedFileReader.

Create an advanced file reader which will accept new file formats and provides output.

public class AdvancedFileReader {

 public void readFileAdvanced(String fileType) {
   if (fileType.equalsIgnoreCase(".docx") || fileType.equalsIgnoreCase(".xlsx")) {
     System.out.println("Success!! Reading advanced file format: " + fileType);
   } else {
     System.out.println("Fail!! Couldn't able to read by Advanced FileReader!!!");
   }
 }
}

Create an adapter which will accept the new file formats and calls the advanced file reader and returns the output. To achieve inheritance I am extending AdvancedFileReader here.

public class FileReaderAdapter extends AdvancedFileReader {

 public void readFile(String fileType) {
   readFileAdvanced(fileType);
 }
}

Modify the MyFileReader so that I will call the adapter for the other file formats.

public class MyFileReader implements FileReader {
 FileReaderAdapter fileReaderAdapter = new FileReaderAdapter();

 public void readFile(String fileType) {
   System.out.println("File Type is: " + fileType);

   if (fileType.equalsIgnoreCase(".txt") || fileType.equalsIgnoreCase(".pdf")) {
     System.out.println("Success!! Reading the file format : " + fileType);
   } else {
     fileReaderAdapter.readFile(fileType);
   }
 }
}

Now time to test the Adapter Design Pattern. Call the MyFileReader with new file formats and check the output.

public class AdapterPatternTest {
 public static void main(String[] args) {

   System.out.println("ADAPTER DESIGN PATTERN - INHERITANCE");
   FileReader fileReader = new MyFileReader();
   fileReader.readFile(".txt");

   System.out.println("\n");
   fileReader.readFile(".pdf");

   System.out.println("\n");
   fileReader.readFile(".docx");

   System.out.println("\n");
   fileReader.readFile(".xlsx");

   System.out.println("\n");
   fileReader.readFile(".aaa");

 }
}

OUTPUT


ADAPTER DESIGN PATTERN - INHERITANCE
File Type is: .txt
Success!! Reading the file format : .txt


File Type is: .pdf
Success!! Reading the file format : .pdf


File Type is: .docx
Success!! Reading advanced file format: .docx


File Type is: .xlsx
Success!! Reading advanced file format: .xlsx


File Type is: .aaa
Fail!! Couldn't able to read by Advanced FileReader!!!

IMPLEMENTATION - USING COMPOSITION

In FileReaderAdapter, instead of extending the AdvancedFileReader, create an instance for AdvancedFileReader and all the respective method to read advanced file formats.

public class FileReaderAdapter {

 AdvancedFileReader advancedFileReader = null;

 public void readFile(String fileType) {
   advancedFileReader = new AdvancedFileReader();

   advancedFileReader.readFileAdvanced(fileType);
 }
}

The output should be same. Checkout the Complete Source Code here.

Hope this example clarifies the Adapter Design Pattern. Please share your thoughts in the comment box.
Happy Knowledge Sharing!!!

No comments :

Post a Comment