Adapter Pattern Example Cont...

The other way is to change your application code at each place to use  readFile() method of your new library in place of  readLines(file) . But this will lead  lots of changes in you application code so it is not acceptable as you may end up introducing lot of bugs in the code.

Solution: So the simplest way to solve this problem is to use Adapter pattern here. You can create an adapter class which will act as a wrapper on new third party library and provide the same method readLines(file) as your LegacyFileReader class. This way you can drop your Legacy class and use new class from the new library easily.

Lets implement the Adapter here to solve this problem.
Create an interface as following this will have the same method as in LegacyFileReader class.
LinesReader.java

public interface LinesReader {
                String[] readLines(String fileName);
}

Now create and Adapter class which will implement this interface.

/**
 * This Adapter class provides a wrapper on for the ThirdPartyFileReader
 * To facilitate the user to read file data as lines
 */
public class FileReaderAdapter implements LinesReader{
     
    public FileReaderAdapter(){
    }
   /**
    * Read the file and returns all the text lines from a given text file
    */
    public String[] readLines(String file) {
      try {
         ThirdPartyFileReader fileReader = new ThirdPartyFileReader(file);
         String linesData = new String(fileReader .readFile());
         return linesData.split("/n/r");//break the data in to
                                       // lines using line feed
         } catch (Exception e) {
               e.printStackTrace();
         }
         return null;
    }
 }

You can see here this adapter class has the same method as Legacy class and utilizing the  ThirdPartyFileReader class from new library, without writing full implementation for reading file. Now it easy to replace Legacy class with this adapter class and use the same method readLines(String file) as it is. no need to make any changes in the existing code.

Now you can write a client class to test this adapter class as following

/**
 * Client class to test the FileReaderAdapter
 */
public class AdapterTestClient {
               
                public static void main(String[] args){
                                String file = "E:/Temp.txt";
                                LinesReader readerAdapter = new FileReaderAdapter();
                                String[] lines = readerAdapter.readLines(file);
                                for (int i = 0; i < lines.length; i++) {
                                                System.out.println(lines[i]);
                                }
                }
}

Create a  Temp.txt at E:/ drive  or any place where you like for test I am creating it here with following content

This is the 1st line of the file
This is the 2nd line
this is 3rd line

Now if we run the AdapterTestClient class then in main it will read this Temp.txt file with the help of Adapter class and print the following output.

Output:

This is the 1st line of the file
This is the 2nd line
this is 3rd line

This way we covered the point we explained as Simple interface conversion that just changes operation names and order of arguments

Lets take an other example which is commonly used in the GUI development


 public class ButtonDemo {
             public ButtonDemo() {
                    Button button = new Button("Press me");
                    button.addActionListener(new ActionListener() {
                               public void actionPerformed(ActionEvent e) {
                                            doOperation();
                                }
                     });
              }
             public void doOperation() { 
                       // required code to handle operation 
             }         
 }



Do you see any Adapter pattern here? here Button object expect to be able to invoke the actionPerformed() method on its associated ActionListener object. But the ButtonDemo class does not have this method! It really wants the button to invoke its doOperation() method. The anonymous inner class we instantiated acts as an adapter object, adapting ButtonDemo to ActionListener!


        <--HomePage                              <--PreviousPage

1 comment :