设计模式之适配器模式(Adapter)
场景
您的存储卡中有一些照片,需要将它们传输到计算机上。为了传输它们,您需要某种与计算机端口兼容的适配器,以便将存储卡连接到计算机。在这种情况下,读卡器是适配器。另一个例子是着名的电源适配器; 三脚插头不能连接到双管插座,需要使用电源适配器使其与双叉插座兼容。另一个例子是翻译人员将一个人所说的话翻译成另一个人
维基百科
允许将现有类的接口用作另一个接口。它通常用于使现有类与其他类一起工作而无需修改其源代码。(适配器模式允许您将其他不兼容的对象包装在适配器中,以使其与另一个类兼容。)
以下示例场景
汉语翻译成英语
类适配器
通过继承来实现适配器功能
public class SpeakChinese { public void speakChinese(){ System.out.println("说汉语..."); }}
public interface SpeakEnglish { void speakEnglish();}
public class Translation extends SpeakChinese implements SpeakEnglish { @Override public void speakEnglish() { speakChinese(); System.out.println("===translation==="); System.out.println("Speak English..."); }}
@Test public void clazz(){ SpeakEnglish speakEnglish = new Translation(); speakEnglish.speakEnglish(); }
类图如下所示
类适配器的把SpeakChinese中的方法暴露给了适配器,使用起来成本增加
对象适配器
原理:通过组合来实现适配器功能。
public class TranslationObjectAdapter implements SpeakEnglish { private SpeakChinese speakChinese; public TranslationObjectAdapter(SpeakChinese speakChinese) { this.speakChinese = speakChinese; } @Override public void speakEnglish() { speakChinese.speakChinese(); System.out.println("===translation==="); System.out.println("Speak English..."); }}
测试
@Test public void objectTest(){ SpeakEnglish speakEnglish = new TranslationObjectAdapter(new SpeakChinese()); speakEnglish.speakEnglish(); }
类图如下:
对象适配器和类适配器其实算是同一种思想,只不过实现方式不同,对于适配器模式用法还是有改变的
接口适配器
原理:通过抽象类来实现适配,这种适配稍别于上面所述的适配
现在不只是需要翻译成英语,需要翻译成日语、法语或西班牙语或者需要这几种语言任意组合创建接口
public interface SpeakMany { void speakJpanese(); void speakSpanish(); void speakEnglish(); void speakFrances();}
中间适配器
public abstract class SpeakWrapper implements SpeakMany{ protected SpeakChinese speakChinese; public SpeakWrapper(SpeakChinese speakChinese) { this.speakChinese = speakChinese; } @Override public void speakJpanese() { speakChinese.speakChinese(); } @Override public void speakSpanish() { speakChinese.speakChinese(); } @Override public void speakEnglish() { speakChinese.speakChinese(); } @Override public void speakFrances() { speakChinese.speakChinese(); }}
双语
public class SpeakSpanishAndEnglish extends SpeakWrapper { public SpeakSpanishAndEnglish(SpeakChinese speakChinese) { super(speakChinese); } @Override public void speakEnglish() { super.speakEnglish(); System.out.println("speak English"); } @Override public void speakFrances() { super.speakFrances(); System.out.println("speak France"); }}
测试
@Test public void wrapperTest(){ SpeakMany speakMany = new SpeakSpanishAndEnglish(new SpeakChinese()); speakMany.speakEnglish(); speakMany.speakFrances(); }