Java设计模式之-适配器模式

适配器模式

适配器模式是设计模式中的一种,属于结构型模式。这个模式的主要目标是使得原本不兼容的接口能够相互合作。

就像现实生活中的电源适配器一样,可以使得不同的电源插头可以在不同的电源插座上使用。

主要解决的问题

在软件开发过程中,经常会遇到两个已有的类,它们的功能满足我们的需求,但是它们的接口并不兼容。

如果直接修改这两个类的源代码,可能会引入新的错误,或者破坏已有的测试。

在这种情况下,我们可以使用适配器模式,来提供一个能够调和这两个类接口差异的解决方案。

何时使用适配器模式

  • 你想使用一个已经存在的类,但是它的接口不符合你的需求。
  • 你想创建一个可以复用的类,该类可以与其他不相关的类或者不可预见的类(即那些接口可能不一定兼容的类)协同工作。
  • 你需要使用几个已有的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父接口。

举一个生活中的例子

想象你去了一个外国国家,你带了一个电动剃须刀,但是你发现那个国家的电源插头和你的剃须刀插头不兼容。这时,你需要一个电源适配器,它一头适配你的剃须刀插头,另一头适配那个国家的电源插座。

在这个例子中,电源适配器就扮演了“适配器”的角色。

优点

  • 提高了类的复用性。
  • 增加了类的透明度。
  • 灵活性好。

缺点

  • 过多地使用适配器,会使系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统的复杂性往往来自于这些难以直视的细节。

使用场景

在软件系统中,当你想使用某个类,但是它的接口不符合你的需求,或者你想创建一个可以复用的类,该类可以与其他不相关或不可预见的类协同工作,那么可以使用适配器模式。

代码示例

假设有一个MediaPlayer接口和一个更高级的AdvancedMediaPlayer接口。我们想要让MediaPlayer可以播放更高级的音频,但是我们不想改变现有的类,所以我们创建了一个适配器。

// 媒体播放器接口
public interface MediaPlayer {
   void play(String audioType, String fileName);
}

// 高级媒体播放器接口
public interface AdvancedMediaPlayer {    
   void playVlc(String fileName);
   void playMp4(String fileName);
}

// 创建实现了 AdvancedMediaPlayer 接口的实体类。
public class VlcPlayer implements AdvancedMediaPlayer{
   @Override
   public void playVlc(String fileName) {
      System.out.println("Playing vlc file. Name: "+ fileName);        
   }

   @Override
   public void playMp4(String fileName) {
      //do nothing
   }
}

public class Mp4Player implements AdvancedMediaPlayer{
   @Override
   public void playVlc(String fileName) {
      //do nothing
   }

   @Override
   public void playMp4(String fileName) {
      System.out.println("Playing mp4 file. Name: "+ fileName);        
   }
}

// 创建适配器类,实现 MediaPlayer 接口
public class MediaAdapter implements MediaPlayer {

   AdvancedMediaPlayer advancedMusicPlayer;

   public MediaAdapter(String audioType){
   
      if(audioType.equalsIgnoreCase("vlc") ){
         advancedMusicPlayer = new VlcPlayer();            
      
      }else if (audioType.equalsIgnoreCase("mp4")){
         advancedMusicPlayer = new Mp4Player();
      }   
   }

   @Override
   public void play(String audioType, String fileName) {
   
      if(audioType.equalsIgnoreCase("vlc")){
         advancedMusicPlayer.playVlc(fileName);
      }
      else if(audioType.equalsIgnoreCase("mp4")){
         advancedMusicPlayer.playMp4(fileName);
      }
   }
}

// 创建实现了 MediaPlayer 接口的实体类。
public class AudioPlayer implements MediaPlayer {
   MediaAdapter mediaAdapter; 

   @Override
   public void play(String audioType, String fileName) {        

      // 播放 mp3 音乐文件的内置支持
      if(audioType.equalsIgnoreCase("mp3")){
         System.out.println("Playing mp3 file. Name: " + fileName);            
      } 
      
      // mediaAdapter 提供了播放其他文件格式的支持
      else if(audioType.equalsIgnoreCase("vlc") 
         || audioType.equalsIgnoreCase("mp4")){
         mediaAdapter = new MediaAdapter(audioType);
         mediaAdapter.play(audioType, fileName);
      }
      
      else{
         System.out.println("Invalid media. " + audioType + " format not supported");
      }
   }   
}

在这个例子中,AudioPlayer通过使用MediaAdapter适配器类,可以播放mp3、mp4和vlc格式的音频,而不需要直接实现AdvancedMediaPlayer接口。

你可能感兴趣的:(设计模式,java,设计模式,适配器模式)