0 votes
in Design Patterns by
What is Adapter design pattern ?

2 Answers

0 votes
by
The general idea of an adapter in software development is identical to the one in the physical world. If you have been to different countries, you probably recognized that a lot of them are using differently shaped power sockets. Quite often, they are shaped in a way that the plug of your electrical device doesn’t fit. So, how do you connect the charger of your mobile phone or laptop to these power sockets?

The answer is simple. You get an adapter which you can put into the power socket and then you put your plug into the other end of the adapter. The adapter changes the form of your plug so that you can use it with the power socket. In that example and in most other situations, the adapter doesn’t provide any additional functionality. It just enables you to connect your plug to the power socket.

The Adapter Pattern applies the same idea to object-oriented programming by introducing an additional adapter class between an interface and an existing class.

Adapter Pattern Classes

The adapter class implements the expected interface and keeps a reference to an object of the class you want to reuse. The methods defined by the interface call one or more methods on the referenced object and return a value of the expected type. By doing that, the adapter class fulfills the expected contract by implementing the interface and enables you to reuse existing, incompatible implementations.
0 votes
by
The adapter design pattern falls under the category of a structural design pattern that lets incompatible objects collaborate. It acts as a wrapper between 2 different objects. The adapter catches the call for one object and transforms them to be recognizable by the second object.

Let us understand this with the help of an example of a USB to Ethernet adapter that is used when we have an ethernet interface at one end and the USB interface on the other end. The USB and ethernet are incompatible with each other which is why we require an adapter. The adapter class has a Client class that expects some object type and it has an Adaptee class that offers the same feature but by exposing a different interface. Now to make these both communicate, we have an Adapter class. The client requests the Adapter by using the target interface. The Adapter class translates the request using the Adaptee Interface on the adaptee. The Client receives the results unaware of the adapter’s role. This has been described in the class diagram as shown below:

Class Diagram:

Let us consider that we have a MediaPlayer Interface which is implemented by the AudioPlayer class. The AudioPlayer can play mp3 format by default. Consider another interface AdvancedPlayer that is being implemented by MP4Player class that plays mp4 formats and WAVPlayer that plays wav formats. If we want to make AudioPlayer class play other formats, then we make use of the MediaAdapter class that implements the MediaPlayer Interface and uses the AdvancedPlayer objects for playing the required format. The code implementation of this scenario is as follows:

//MediaPlayer.java

public interface MediaPlayer {

  public void play(String format, String file);

}

//AdvancedPlayer.java

public interface AdvancedPlayer {

  public void playMp4(String file);

  public void playWav(String file);

}

//Mp4Player.java

public class Mp4Player implements AdvancedPlayer{

  @Override

  public void playMp4(String file) {

     System.out.println("MP4 File "+ file + " Playing....");  

  }

  

  @Override

  public void playWav(String file) {

     //do nothing

  }

}

//WAVPlayer.java

public class WAVPlayer implements AdvancedPlayer{

  @Override

  public void playMp4(String file) {

     //do nothing

  }

  

  @Override

  public void playWav(String file) {

     System.out.println("WAV File "+ file + " Playing....");  

  }

}

//MediaAdapter.java

public class MediaAdapter implements MediaPlayer {

  AdvancedPlayer advancedPlayer;

  public MediaAdapter(String format){

     if(format.equalsIgnoreCase("mp4") ){

        advancedPlayer = new Mp4Player();   

     }else if(format.equalsIgnoreCase("wav") ){

        advancedPlayer = new WAVPlayer();   

     }

  }

  @Override

  public void play(String format, String file) {

  

     if(format.equalsIgnoreCase("mp4")){

        advancedPlayer.playMp4(file);

     }

     else if(format.equalsIgnoreCase("wav")){

        advancedPlayer.playWav(file);

     }

  }

}

//AudioPlayer.java

public class AudioPlayer implements MediaPlayer {

  MediaAdapter mediaAdapter;

  @Override

  public void play(String format, String file) {  

     //inbuilt support to play mp3 music files

     if(format.equalsIgnoreCase("mp3")){

        System.out.println("MP3 file " + file +" Playing...");   

     }

     //Make use of Adapter to support different formats

     else if(format.equalsIgnoreCase("wav") || format.equalsIgnoreCase("mp4")){

        mediaAdapter = new MediaAdapter(format);

        mediaAdapter.play(format, file);

     }

     else{

        System.out.println("Format not supported");

     }

  }   

}

//Driver.java

public class Driver {

  public static void main(String[] args) {

     AudioPlayer audioPlayer = new AudioPlayer();

     audioPlayer.play("mp3", "music1.mp3");

     audioPlayer.play("wav", "music2.wav");

     audioPlayer.play("mp4", "music3.mp4");

     audioPlayer.play("avi", "music4.avi");

  }

}

The output of this code would be:

MP3 file music1.mp3 Playing...

WAV File music2.wav Playing...

MP4 File music3.mp4 Playing...

Format not supported

14. What is a Proxy Design Pattern?

Proxy design pattern falls under the category of structural design that represents the functionality of other classes. This pattern lets the developers provide a substitute for another object. This is called a proxy object. This helps to control the access to the original object and allows us to perform many tasks before or after the request reaches the original object.

As shown in the figure above, in this pattern, we have a ServiceInterface interface that has some operation. This interface is being implemented by a Service class and a Proxy class. The Service class has useful business logic and the Proxy class has a reference field pointing to the service object. Once the proxy finishes processing lazy initialization, logging, caching etc, the request will be passed to the service object. And finally, we have a client that works with the services and the proxies by using the interface. This helps to pass proxy objects to any piece of code.

Related questions

0 votes
asked Jul 24, 2023 in Design Patterns by SakshiSharma
0 votes
asked Jul 23, 2023 in Design Patterns by Robindeniel
...