我们之前已经说过对象适配器模式,有兴趣的读者可以阅读 对象适配器模式。
定义
适配器模式就是把一个类的接口转换成客户端所期待的另外一种接口,从而使原接口不匹配而无法一起工作的两个类能在一起工作。从功能上说,不兼容的接口都拥有相似或者相同的功能,但是对于客户端期望的接口不兼容,通常我们通过修改该类的接口来解决接口不兼容的问题,但是我们不愿意为了一个功能修改哥哥依赖接口,或者我们压根就没有对象类的源代码,适配器就派上用场了。
适配器优点
- 使目标类和被适配类解耦。
- 增加了类的透明性和复用性,将具体的实现封装在适配器中,对于客户端来说是透明的。
- 灵活性、拓展性比较好,符合开闭原则。
角色
- 目标接口(Target):定义一个客户端使用的指定接口。
- 客户端(Client):使用目标接口,完成功能。
- 被适配者(Adaptee):一个现存需要适配成目标接口的类。
- 适配器(Adapter):负责将被适配者接口转换为 Target 接口。这是该模式的核心。
场景重现
假设现在有一个人只会说英语,但是目标类接口要求可以说英语、法语、汉语。这时候 英语就是被适配者,我们的同声翻译就是适配器,用于适配英语同声传译到目标接口所期望的语言。
代码实现
被适配者,只会英语
/** * 被适配器 */ public class EnglishSpeaker { public void speakEnglish() { System.out.println("I can speak english."); } }
目标接口,需要会说 英语、法语、汉语。
/** * 目标接口类:英语、法语、汉语 */ public interface SpeakTarget { void speakEnglish(); void speakChinese(); void speakFrench(); }
定义我们的同声翻译,将英语同声翻译为目标接口期望的功能。我们继承被适配者,同时实现 目标接口。
/** * 同声翻译适配器 */ public class SpeakAdapter extends EnglishSpeaker implements SpeakTarget { public SpeakAdapter() { } @Override public void speakChinese() { System.out.println("通过适配器,将英语转化为中文:我可以说中文"); } @Override public void speakFrench() { System.out.println("通过适配器,将英语转化为法语:我可以说法语了"); } @Override public void speakEnglish() { super.speakEnglish(); } }
Client
/** * 客户端 */ public class Client { public static void main(String[] args) { SpeakTarget speakTarget = new SpeakAdapter(); speakTarget.speakChinese(); speakTarget.speakEnglish(); speakTarget.speakFrench(); } }
打印
通过适配器,将英语转化为中文:我可以说中文 I can speak english. 通过适配器,将英语转化为法语:我可以说法语了