Explain the Java adapter mode in detail

  • 2021-07-10 19:45:47
  • OfStack

Shortly after the holiday, there is nothing to write. Today, I will talk about the influence of design pattern on development. Up to now, I feel that the influence of design pattern on development is quite great.

Let's talk briefly about adapter mode this time. Maybe the adapter pattern feels like a chicken rib, but it is used in a lot of places, especially when developing cooperatively.

1. Adapter mode

Adapter pattern, which acts as a bridge connecting two interfaces. This concept feels a little bit like that. Friends who seldom use interfaces may not feel anything. Friends who often program for interfaces can resonate. Simply put, they write an adapter (converter) to connect objects.

2. Adapter mode usage

There are two java adapter patterns, class adapter and object adapter

(1) Class adapter demo

Class adapters mainly use inheritance to connect two interfaces. We assume that interface A and interface B are docked.

Write interface B first


public interface MP4{
 void play();
}

Implementation class of interface B


public class ExpensiveMP4 implement MP4{
 public void play(){
   // todo
 }
}

Interface A


public interface Player{
  void action();
}

If you have these classes in your project, then you find that the operation to be written in the action () method is the operation "//todo" in ExpensiveMP 4 play (), so you don't have to write it again and find a way to adapt them. So, you want to call play of ExpensiveMP4 when externally calling Player. If you use a class adapter, you can write this


public class ExpensiveAdapter extends ExpensiveMP4 implement Player{
 public void action(){
  play();
 }
}

In this way, the two interfaces are connected, but I generally don't use class adapters, so I feel that this approach is not very flexible, and in java, inheritance is used as little as possible, and combination is used as much as possible. And I don't think this writing is very comfortable.

(2) Object adapter demo

The above class adapters are connected by "inheritance", while the object adapters here are connected by "combination". We assume that interface A and interface B are docked. Use the MP4 interface, the Player interface, and the ExpensiveMP4 class above.

At this time, if we use the object adapter, we can write this.


public class PlayerAdapter implement Player{
 public ExpensiveMP4 expensiveMP4;
 
 public PlayerAdapter (){
  this.expensiveMP4 = new ExpensiveMP4();
 }  

 public void action(){
  if(expensiveMP4 != null){
    expensiveMP4 .play();
  }
 }

}

It feels like it's not very flexible. expensiveMP4 is like a dead one. It has no soul. OK, let's change it.


public class PlayerAdapter implement Player{
 public ExpensiveMP4 expensiveMP4;
 
 public PlayerAdapter (ExpensiveMP4 expensiveMP4){
  this.expensiveMP4 = expensiveMP4;
 }  

 public void action(){
  if(expensiveMP4 != null){
    expensiveMP4 .play();
  }
 }

}

This is much better than just now, much more flexible than just now, but it always feels a little ordinary. We should write the code a little artistically. Abstract is art. OK, change it again.


public class PlayerAdapter implement Player{
 public MP4 mp4;
 
 public PlayerAdapter (MP4 mp4){
  this.mp4 = mp4;
 }  

 public void action(){
  if(mp4!= null){
    mp4.play();
  }
 }

}

Maybe this will look better. It's easier to see how to adapt the two interfaces.

3. Use scenarios for adapter patterns

(1) One of the scenarios used is like the one mentioned above, with two interfaces. You actively want to connect the two interfaces and write an adapter. I feel that this situation is not very common, because most of the time, one entity class object calls another entity class object.

(2) Passive use, which I may see more. For example, chestnuts, extreme chestnuts, you and your companions have cooperated in development, your companions have written one part, you have written one part, and now the two parts have to be docked. After docking, you find that both of them have customized interfaces, and both of them have finished development and don't want to change them. What should I do? I can only write one adapter to adapt to the two interfaces. Or you redefine the interface when you develop a new version, and when you want to write and adapt to the old version, you can also use adapter mode for convenience.


Related articles: