GOF(六)-适配器模式【推荐】

导言:前5篇文章主要将的创建型设计模式(创建对象、实例),这里开始讲解结构型设计模式。结构型设计模式主要关注的是类和对象的组合,简化设计。

适配器模式(Adapter Pattern)

适配器模式是将两个不兼容的接口连接到一起,所以属于结构型。比如:家用电器使用的是直流电,那么220V的交流电如何使用呢?这时就需要电源适配器来解决接口不兼容的问题;除此之外,如果一个不会英语的人想和外国人交流,就需要一个翻译官,而翻译官就将两个无法交流的人联系到了一起。

适配器模式可以分为4种类型:类适配器模式对象适配器模式、单接口适配器模式(缺省适配器模式)和双向适配器模式。由于后两种复杂且不常用,这里省略对其的介绍。


UML的相关知识,可以访问我的另外一篇博文
GOF(六)-适配器模式【推荐】_第1张图片


类适配器模式

taget:想要的目标结果

/**
 * @description:
 * 作为Traget,适配的结果
 *     即:将中文转为英文,英文作为中文转换的最终结果
 */
public interface EnglishLanguage {

    String talk();
}

写一个他的实现方法(可以省略,这里用于对比测试结果)

public class EnglishPeople implements EnglishLanguage {
    @Override
    public String talk() {
        return "English People Said Something! 普通类";
    }
}

Adaptee老的接口(要被适配的类或方法)

/**
 * @description:
 *  Adaptee  被适配的对象
 *      即:老的接口,需要被转换的类或方法
 */
public class ChineseLanguage {

    public String talk() {
        return "Chinese People Said Something! 被适配的类";
    }
}

Adapter(翻译官) 提供转换功能。
类适配模式: 继承老的接口(被转换的接口Adaptee),实现目标接口(Target)

/**
 * @description:
 * Adapter  转换方法
 *      类适配模式: 继承老的接口(被转换的接口Adaptee),实现目标接口(Target)
 */
public class TranslationAdapter extends ChineseLanguage implements EnglishLanguage {

    @Override
    public String talk() {
        System.out.println("翻译官登场!闲人避让! ");
        System.out.println("TranslationAdapter 开始调用父类的talk方法:");
        // 由于继承ChineseLanguage, 所以super.talk()会调用ChineseLanguage的talk()方法
        return super.talk();
    }
}

当写完翻译官(Adapter【适配器】)之后回头看老接口(Adaptee【被适配的】),截图展示(注意画横线的小标识)
【这里的 I 指的是接口,并且指向目标接口(target)】
GOF(六)-适配器模式【推荐】_第2张图片
并且目标接口(target)有了两个实现方法(因为有两个类实现了它)
GOF(六)-适配器模式【推荐】_第3张图片
测试代码:

    public static void main(String[] args) {

        // 注意:由于实现了一个接口,所以都使用EnglishLanguage接收

        // 调用普通方法
        EnglishLanguage englishLanguage = new EnglishPeople();
        System.out.println(englishLanguage.talk());

        // 调用被适配的老接口
        EnglishLanguage chineseLanguage = new TranslationAdapter();
        System.out.println(chineseLanguage.talk());

        // 以后想用老接口,直接找Adatper(翻译官)就行了
    }

结果展示:

English People Said Something! 普通类
翻译官登场!闲人避让! 
TranslationAdapter 开始调用父类的talk方法:
Chinese People Said Something! 被适配的类

总结一下类适配器模式: 适配类【翻译官】需要继承老接口,实现目标接口


对象适配器模式

老接口(Adaptee【ChineseLanguage】)、目标接口(Target【EnglishLanguage】)都与上面一致,就翻译官(Adapter)发生了改变。

Adapter(翻译官)代码:
对象适配模式: 关联老的接口(被转换的接口Adaptee)【将老接口作为属性】,实现目标接口(Target)

/**
 * @description:
 * Adapter  转换方法
 *      对象适配模式: 
 *          关联老的接口(被转换的接口Adaptee)【将老接口作为属性】
 *          实现目标接口(Target)
 */
public class TranslationAdapter implements EnglishLanguage {

    private ChineseLanguage chineseLanguage;

    // TranslationAdapter的有参构造函数,将老接口作为参数传入方法获取实例
    public TranslationAdapter(ChineseLanguage chineseLanguage) {
        this.chineseLanguage = chineseLanguage;
    }

    @Override
    public String talk() {
        System.out.println("翻译官登场!闲人避让! ");
        System.out.println("TranslationAdapter 开始调用父类的talk方法:");
        // 由于关联ChineseLanguage
        // 所以this.chineseLanguage.talk()会调用ChineseLanguage的talk()方法
        return this.chineseLanguage.talk();
    }
}

当写完翻译官(Adapter【适配器】)之后回头看老接口(Adaptee【被适配的】)
发现没有任何标识了(因为作为了翻译官的属性)
GOF(六)-适配器模式【推荐】_第4张图片
并且目标接口(target)还是两个实现方法(因为有两个类实现了它)
GOF(六)-适配器模式【推荐】_第5张图片
测试代码:

    public static void main(String[] args) {

        // 注意:由于实现了一个接口,所以都使用EnglishLanguage接收

        // 调用普通方法
        EnglishLanguage englishLanguage = new EnglishPeople();
        System.out.println(englishLanguage.talk());

        // 调用被适配的老接口,需要传入参数
        EnglishLanguage chineseLanguage = 
        			new TranslationAdapter(new ChineseLanguage());
        System.out.println(chineseLanguage.talk());

        // 以后想用老接口,直接找Adatper(翻译官)就行了
    }

结果展示:

English People Said Something! 普通类
翻译官登场!闲人避让! 
TranslationAdapter 开始调用父类的talk方法:
Chinese People Said Something! 被适配的类

总结一下对象适配器模式: 老接口成为适配类【翻译官】的属性,并且适配类【翻译官】需要实现目标接口

适配器模式原理很简单,但是使用方式千变万化,通常会结合其他模式一同使用。


代码已经上传到Git:请点击访问

如果大家对于适配器模式还有更多的使用技巧和使用心得,欢迎评论并在评论中分享自己的链接!

你可能感兴趣的:(GOF(六)-适配器模式【推荐】)