文章内容
一、什么是适配器模式
适配器模式,将一个类的接口转换为客户端希望的另一个接口,使其原本由于不兼容而不能一起工作的类能一起协同工作。
适配器模式,属于结构型设计模式。
二、适配器模式角色
- 目标接口:客户端希望的接口类,可以是抽象类或接口类。
- 适配者类:需要转换为目标接口的被适配类。
- 适配器类:通过继承或依赖适配者类,把适配者接口转换为目标接口,让客户端直接调用目标接口的方法访问适配者。被适配者对客户端来说是透明的。
三、适配器模式分类
- 类适配器模式:适配器类,通过继承适配者接口,实现目标接口,完成适配者接口向目标接口的转换。
- 对象适配器模式:适配器类,通过依赖适配者接口,实现目标接口,完成适配者接口向目标接口的转换。由于类适配器需要继承适配者类,一定程度上耦合度比对象适配器更高,对象适配器更符合“合成复用原则”。
- 接口适配器模式:当客户端不需要全部实现目标接口提供的方法时,可先定义一个抽象类实现接口,并为该抽象接口的所有方法提供一个默认空实现,这样该抽象类的子类就可以有选择性的重写父类的方法来实现需求。
四、适配器模式UML图
1、类适配器模式

2、对象适配器模式

3、接口适配器模式

五、适配器模式demo示例
1、Demo需求
手机想要投影到投影仪上,由于手机是Type-c接口,投影仪是VGA接口。 不能直接投影,需要一个适配器,将视频信号从Type-c口转到VGA口,最后才能输出到大屏幕上。
2、类适配器模式代码实现
01 02 03 04 05 06 07 08 09 10 11 | /** * 适配者类 * * 手机想要投影到投影仪上,由于手机是Type-c接口,投影仪是VGA接口。 * 不能直接投影,需要一个适配器,将视频信号从Type-c口转到VGA口,最后才能输出到大屏幕上。 */ public class Phone { public void typec(){ System.out.println( "手机输出type-c接口。。。" ); } } |
1 2 3 4 5 6 | /** *目标接口 */ public interface VGA { void vgaInterface(); } |
01 02 03 04 05 06 07 08 09 10 | /** * 适配器类,将手机号的type-c接口转换为投影仪的VGA接口 */ public class VGAAdapter extends Phone implements VGA { public void vgaInterface() { super .typec(); System.out.println( "已得到type-c接口信息" ); System.out.println( "已将type-c接口信息转换为vga接口信息...." ); } } |
1 2 3 4 5 6 7 8 9 | /** * 客户端测试类 */ public class Client { public static void main(String[] args) { VGA vga = new VGAAdapter(); vga.vgaInterface(); } } |
控制台输入日志:
1 2 3 | 手机输出type-c接口。。。 已得到type-c接口信息 已将type-c接口信息转换为vga接口信息.... |
3、对象适配器模式代码实现
01 02 03 04 05 06 07 08 09 10 11 | /** * 适配者类 * * 手机想要投影到投影仪上,由于手机是Type-c接口,投影仪是VGA接口。 * 不能直接投影,需要一个适配器,将视频信号从Type-c口转到VGA口,最后才能输出到大屏幕上。 */ public class Phone { public void typec(){ System.out.println( "手机输出type-c接口。。。" ); } } |
1 2 3 4 5 6 | /** *目标接口 */ public interface VGA { void vgaInterface(); } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | /** * 对象适配器类 */ public class VgaObjAdapter implements VGA { //依赖适配者类 private Phone phone; // 通过构造方法初始化适配者对象 public VgaObjAdapter(Phone phone){ this .phone = phone; } public void vgaInterface() { phone.typec(); System.out.println( "已获取type-c接口数据" ); System.out.println( "已通过对象适配器模式,将type-c接口转换为vga接口" ); } } |
1 2 3 4 5 6 7 8 9 | /** * 对象适配器客户端测试类 */ public class Client { public static void main(String[] args) { VGA vga = new VgaObjAdapter( new Phone()); vga.vgaInterface(); } } |
控制台输入日志:
1 2 3 | 手机输出type-c接口。。。 已获取type-c接口数据 已通过对象适配器模式,将type-c接口转换为vga接口 |
4、接口适配器模式代码实现
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 | /** * 目标接口类:接口适配器模式 * * 多个方法 */ public interface Target { /** * typec适配 */ void typec(); /** * vga适配 */ void vgaInterface(); /** * hdmi适配 */ void hdmiInterface(); } |
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | /** * 类似适配者类: * 定义目标接口抽象类,将目标接口空实现 */ public abstract class AbstractTarget implements Target { public void typec() { System.out.println( "typec ...." ); } public void vgaInterface() { } public void hdmiInterface() { } } |
01 02 03 04 05 06 07 08 09 10 11 | /** * 适配器类,覆写vag适配方法 */ public class VGAAdapter extends AbstractTarget { @Override public void vgaInterface() { super .typec(); System.out.println( "以获取type-c接口数据" ); System.out.println( "已通过接口适配器,将type-c接口转换为vga接口" ); } } |
1 2 3 4 5 6 7 8 9 | /** * 客户端测试类 */ public class Client { public static void main(String[] args) { VGA vga = new VGAAdapter(); vga.vgaInterface(); } } |
控制台输入日志:
1 2 3 | 手机输出type-c接口。。。 已得到type-c接口信息 已将type-c接口信息转换为vga接口信息.... |