浏览次数:2,914
                     点赞次数:0
                     评论次数:0
                     发布日期:2022-06-15
                     文章字数:1.4k
                     阅读时长:3.9分钟
                
                死磕设计模式—适配器模式
前言(八问知识体系)

1.简介
- 
什么是适配器模式? - 1.将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作
- 2.适配器模式既可以作为类结构型模式,也可以作为对象结构型模式
- 3.适配器模式属于结构型模式
- 4.适配器实现了统一管理,一个目标是适配接口对象多个适配器类
 
- 
适配器模式的优缺点? - 优点
- 1.将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码
- 2.增加了类的透明性和复用性,将具体的实现封装在适配者类中
- 3.灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器
- 4.对象适配器模式还可以将不通的适配者适配到同一个目标接口上
 
- 缺点
- 1.过多的使用适配器类会让程序变得复杂
- 2.类适配器模式还存在单继承的问题
 
 
- 优点
2.类图
2.1.类适配器类图

注意事项:Java是单继承机制,类适配器需要继承源类,这是一个缺点,同时源类的方法也在适配器类中暴漏出来,增加类使用的成本。
2.2.对象适配器类图

PS:对象适配器模式更多是为类解决类适配器中的单继承问题,修改类实现方式,根据合成复用原则,使用组合的方式代替继承,同时使用的成本降低。
2.3.接口适配器类图

PS:接口适配器就是重写接口中我们需要使用的方法,但是接口中会存在很多方法,所以我们会使用一个抽象类适配器采用默认空方法来实现接口,使用的时候采用内部类来覆写。
3.代码示例
3.1.类适配器
被适配类
@Slf4j
public class Adaptee {
    /**
     * outPut220V
     *
     * @return 220V电压
     * @description 输出220V的电压
     * @author luokangyuan
     * @date 2019/11/3 16:49
     * @version 1.0.0
     */
    public int outPut220V() {
        log.info("输出220V的电压");
        return 220;
    }
}
目标抽象接口
public interface Target {
    /**
     * outPut22V
     *
     * @description 输出22V的电压
     * @return 22V的电压
     * @author luokangyuan
     * @date 2019/11/3 16:50
     * @version 1.0.0
     */
    int outPut22V();
}
适配器类
public class Adapter extends Adaptee implements Target {
    @Override
    public int outPut22V() {
        // 1.得到需要适配的数据
        int i = outPut220V();
        // 2.适配转换操作
        int result = i / 10;
        // 返回适配后结果
        return result;
    }
}
客户端
public class Phone {
    /**
     * charging
     *
     * @param target : 适配接口
     * @description 手机充电方法
     * @author luokangyuan
     * @date 2019/11/3 17:00
     * @version 1.0.0
     */
    public void charging(Target target) {
        // 得到期望结果,开始后续操作
        int i = target.outPut22V();
        log.info("当前电压为{},开始充电操作", i);
    }
}
测试调用
public static void main(String[] args) {
    Phone phone = new Phone();
    phone.charging(new Adapter());
}
3.2.对象适配器
由于类适配器需要继承源类,由于Java是单继承,所以存在很大的局限性,所以出现类对象适配器,就是在适配器类中不再使用继承源类的方式,而是使用源类的实例来解决兼容性问题,即持有Src类,实现Dst类,完成适配。
根据合成复用原则,在系统中尽量使用关联关系来代替继承关系,对象适配器模式才是适配器模式中最常用的一种模式。
被适配类
public class Adaptee {
    /**
     * outPut220V
     *
     * @return 220V电压
     * @description 输出220V的电压
     * @author luokangyuan
     * @date 2019/11/3 16:49
     * @version 1.0.0
     */
    public int outPut220V() {
        log.info("输出220V的电压");
        return 220;
    }
}
目标抽象接口
public interface Target {
    /**
     * outPut22V
     *
     * @description 输出22V的电压
     * @return 22V的电压
     * @author luokangyuan
     * @date 2019/11/3 16:50
     * @version 1.0.0
     */
    int outPut22V();
}
适配器类
public class Adapter implements Target {
    private Adaptee adaptee;
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
    @Override
    public int outPut22V() {
        // 1.得到需要适配的数据
        int i = adaptee.outPut220V();
        // 2.适配转换操作
        int result = i / 10;
        // 返回适配后结果
        return result;
    }
}
客户端
public class Phone {
    /**
     * charging
     *
     * @param target : 适配接口
     * @description 手机充电方法
     * @author luokangyuan
     * @date 2019/11/3 17:00
     * @version 1.0.0
     */
    public void charging(Target target) {
        // 得到期望结果,开始后续操作
        int i = target.outPut22V();
        log.info("当前电压为{},开始充电操作", i);
    }
}
测试调用
public static void main(String[] args) {
    Phone phone = new Phone();
    phone.charging(new Adapter(new Adaptee()));
}
3.3.接口适配器
源接口
public interface IAdaptee {
    void method1();
    void method2();
    void method3();
    void method4();
}
抽象的接口适配器类
public  abstract  class AbsAdapter implements IAdaptee{
    @Override
    public void method1() {
    }
    @Override
    public void method2() {
    }
    @Override
    public void method3() {
    }
    @Override
    public void method4() {
    }
}
客户端
@Slf4j
public class Client {
    public static void main(String[] args) {
        new AbsAdapter() {
            @Override
            public void method1() {
                log.info("我只是使用了接口中的method1");
            }
        };
    }
}
4.总结
- 
适配器模式的使用场景? - 1.系统需要使用现有的类,而这些类的接口不符合系统的需要
 
- 
适配器模式的使用案例? - 1.SpringMvc中的HandlerAdapter使用了适配器模式
- 2.java.util.Arrays#asList()也使用了适配器模式
- 3.spring AOP中的AdvisorAdapter使用了适配器模式
- 适配者类角色
 
