【结构型】- 适配器模式
适配器模式的定义:将一个类的接口转换成客户希望的另一个接口。适配器让那些接口不兼容的类可以一起工作。
适配器模式可以分为:类适配器模式、对象适配器模式、接口适配器模式。
针对前两种适配器模式,下面以播放器为例。老版的播放器(Player)只支持mp4格式的视频文件,而新版的播放器(AdvancedPlayer)在支持mp4的基础上还支持rmvb、avi等格式。实现目标:在不改变老版播放器接口文件的前提下,实现老版的播放器也能支持播放rmvb、avi等格式的视频文件。
类适配器模式
老版播放器
package com.design.pattern.adapter; public interface Player { void play(String audioType, String audioName); }
老版播放器的实现类
package com.design.pattern.adapter; public class PlayerImpl implements Player { @Override public void play(String audioType, String audioName) { if("mp4".equalsIgnoreCase(audioType)) { System.out.println("【旧版播放器】开始播放mp4格式的视频:"+audioName); } else { System.out.println("【旧版播放器】目前仅支持播放mp4格式的视频,不支持当前格式文件:"+audioName); } } }
新版播放器接口
package com.design.pattern.adapter; public interface AdvancedPlayer { void playRmvb(String audioName); void playAvi(String audioName); }
新版播放器实现类
package com.design.pattern.adapter; public class AdvancedPlayerImpl implements AdvancedPlayer { @Override public void playRmvb(String audioName) { System.out.println("【新版播放器】开始播放rmvb格式的视频:"+audioName); } @Override public void playAvi(String audioName) { System.out.println("【新版播放器】开始播放avi格式的视频:"+audioName); } }
适配器类
package com.design.pattern.adapter; // 实现步骤一:实现旧版播放器接口Player,同时继承新版播放器的具体实现。 public class PlayerAdapter extends AdvancedPlayerImpl implements Player { @Override public void play(String audioType, String audioName) { // 实现步骤二:复写播放器的播放方法 if("rmvb".equalsIgnoreCase(audioType)) { super.playRmvb(audioName); } else if("avi".equalsIgnoreCase(audioType)) { super.playAvi(audioName); } else { System.out.println("【适配器】开始播放mp4格式的视频:"+audioName); } } }
测试类
package com.design.pattern.adapter; public class Ctest01 { public static void main(String[] args) { // 旧式的播放器只支持播放mp4格式的视频文件 Player mp4Player = new PlayerImpl(); mp4Player.play("mp4", "适配器模式.mp4"); mp4Player.play("rmvb", "适配器模式.rmvb"); mp4Player.play("avi", "适配器模式.avi"); System.out.println("-----------------------------------"); // 使用[类适配器]后,可以兼容rmvb,avi格式的视频文件 Player adapterPlayer = new PlayerAdapter(); adapterPlayer.play("mp4", "适配器模式.mp4"); adapterPlayer.play("rmvb", "适配器模式.rmvb"); adapterPlayer.play("avi", "适配器模式.avi"); } }
测试结果:
【旧版播放器】开始播放mp4格式的视频:适配器模式.mp4 【旧版播放器】目前仅支持播放mp4格式的视频,不支持当前格式文件:适配器模式.rmvb 【旧版播放器】目前仅支持播放mp4格式的视频,不支持当前格式文件:适配器模式.avi ----------------------------------- 【适配器】开始播放mp4格式的视频:适配器模式.mp4 【新版播放器】开始播放rmvb格式的视频:适配器模式.rmvb 【新版播放器】开始播放avi格式的视频:适配器模式.avi
对象适配器模式
原理:通过组合来实现适配器功能。
对象适配器类
package com.design.pattern.adapter.obj; import com.design.pattern.adapter.AdvancedPlayer; import com.design.pattern.adapter.Player; public class PlayerAdapter implements Player { private AdvancedPlayer advancedPlayer; public PlayerAdapter(AdvancedPlayer advancedPlayer) { this.advancedPlayer = advancedPlayer; } @Override public void play(String audioType, String audioName) { if ("mp4".equalsIgnoreCase(audioType)) { System.out.println("【适配器】开始播放mp4格式的视频:"+audioName); } else if ("avi".equalsIgnoreCase(audioType)) { advancedPlayer.playAvi(audioName); } else if ("rmvb".equalsIgnoreCase(audioType)) { advancedPlayer.playRmvb(audioName); } } }
测试类
package com.design.pattern.adapter.obj; import com.design.pattern.adapter.AdvancedPlayer; import com.design.pattern.adapter.AdvancedPlayerImpl; import com.design.pattern.adapter.Player; import com.design.pattern.adapter.PlayerImpl; public class Ctest01 { public static void main(String[] args) { // 旧式的播放器只支持播放mp4格式的视频文件 Player mp4Player = new PlayerImpl(); mp4Player.play("mp4", "适配器模式.mp4"); mp4Player.play("rmvb", "适配器模式.rmvb"); mp4Player.play("avi", "适配器模式.avi"); System.out.println("-----------------------------------"); // 使用[对象适配器]后,可以兼容rmvb,avi格式的视频文件 AdvancedPlayer advancedPlayer = new AdvancedPlayerImpl(); Player adapterPlayer = new PlayerAdapter(advancedPlayer); adapterPlayer.play("mp4", "适配器模式.mp4"); adapterPlayer.play("rmvb", "适配器模式.rmvb"); adapterPlayer.play("avi", "适配器模式.avi"); } }
测试结果如下:
【旧版播放器】开始播放mp4格式的视频:适配器模式.mp4 【旧版播放器】目前仅支持播放mp4格式的视频,不支持当前格式文件:适配器模式.rmvb 【旧版播放器】目前仅支持播放mp4格式的视频,不支持当前格式文件:适配器模式.avi ----------------------------------- 【适配器】开始播放mp4格式的视频:适配器模式.mp4 【新版播放器】开始播放rmvb格式的视频:适配器模式.rmvb 【新版播放器】开始播放avi格式的视频:适配器模式.avi
接口适配器模式
原理:通过抽象类来实现适配,这种适配稍别于上面所述的适配。
当存在这样一个接口,其中定义了N多的方法,而我们现在却只想使用其中的一个到几个方法,如果我们直接实现接口,那么我们要对所有的方法进行实现,哪怕我们仅仅是对不需要的方法进行置空(只写一对大括号,不做具体方法实现)也会导致这个类变得臃肿,调用也不方便,这时我们可以使用一个抽象类作为中间件,即适配器,用这个抽象类实现接口,而在抽象类中所有的方法都进行置空,那么我们在创建抽象类的继承类,而且重写我们需要使用的那几个方法即可。