欢迎光临散文网 会员登陆 & 注册

java设计模式—适配器模式

2023-07-20 22:16 作者:大大的月亮吖吖  | 我要投稿

## 适配器模式

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


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


## 主要解决的问题

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


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


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


## 何时使用适配器模式


- 你想使用一个已经存在的类,但是它的接口不符合你的需求。

- 你想创建一个可以复用的类,该类可以与其他不相关的类或者不可预见的类(即那些接口可能不一定兼容的类)协同工作。

- 你需要使用几个已有的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父接口。


## 举一个生活中的例子

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


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

## 优点

- 提高了类的复用性。

- 增加了类的透明度。

- 灵活性好。

## 缺点

- 过多地使用适配器,会使系统非常零乱,不易整体进行把握。比如,明明看到调用的是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设计模式—适配器模式的评论 (共 条)

分享到微博请遵守国家法律