结构型模式(一):适配器模式

1、模式的定义与特点

适配器模式(Adapter):将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
适配器模式分为 类 结 构 型 模 式 \color{orange}{类结构型模式} 对 象 结 构 型 模 式 \color{orange}{对象结构型模式} 两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。

两者均实现目标角色接口,目标接口和适配者类的代码也可以相同,区别是:
类适配器模式:适配器类继承适配者类,是继承关系。
对象适配器模式:适配器类持有适配者类对象的引用,是组合或聚合关系。

适配器模式的优点:
1、客户端通过适配器可以透明地调用目标接口。
2、复用了现存的类,程序员不需要修改原有代码而重用现有的适配者类。
3、将目标类和适配者类解耦,解决了目标类和适配者类接口不一致的问题。

适配器模式的缺点:
对类适配器来说,更换适配器的实现过程比较复杂。

2、模式的结构

适配器模式包含以下主要角色:
1、目标(Target)接口角色:当前系统业务所期待的接口,它可以是抽象类或接口。
2、适配者(Adaptee)类,也称源角色:它是被访问和适配的现存组件库中的组件类或接口。
3、适配器(Adapter)类角色:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
在这里插入图片描述

图1 类适配器模式的结构图

在这里插入图片描述

图2 对象适配器模式的结构图

3、模式的应用场景

1、以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致。
2、使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。

4、模式的扩展

适配器模式可扩展为双向适配器模式,双向适配器类既可以把适配者接口转换成目标接口,也可以把目标接口转换成适配者接口。
在这里插入图片描述

图3 双向适配器模式的结构图

5、模式的实现

说明:
对象适配器模式中的“目标接口”和“适配者类”的代码可以同类适配器模式一样,只要修改适配器类和客户端的代码即可。

5.1 类适配器模式

在这里插入图片描述

图4 类适配器代码结构图

目标角色ITarget:

package com.example.designpattern.classadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 * 目标角色:期待的接口
 */
interface ITarget {
    public void a();

    public void b();
}

源角色Adaptee:

package com.example.designpattern.classadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 * 源角色:需要适配的类
 */
class Adaptee {
    public void a() {
        System.out.println("adaptee: a()实现");
    }
}

适配器角色Adapter:

package com.example.designpattern.classadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 * 适配器角色:把源角色转换为目标接口、核心类
 *
 * 将需要适配的Adaptee适配为ITarget目标类型
 */
class Adapter extends Adaptee implements ITarget {
    @Override
    public void b() {
        System.out.println("adapter: b()实现");
    }
}

调用:

package com.example.designpattern.classadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 */
class Client {
    public static void main(String[] args) {
        ITarget iTarget = new Adapter();
        iTarget.a();
        iTarget.b();
    }
}

测试结果:
在这里插入图片描述

图5 类适配器代码测试结果

5.2 对象适配器模式

在这里插入图片描述

图6 对象适配器模式代码结构图

目标角色ITarget:

package com.example.designpattern.objectadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 * 目标角色:客户端期待使用的类或接口
 */
interface ITarget {
    public void a();

    public void b();
}

源角色AbstractAdaptee:

package com.example.designpattern.objectadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 * 源角色:需要适配的类
 */
abstract class AbstractAdaptee {
    public abstract void a();
}

源角色AbstractAdaptee的子类Adaptee1:

package com.example.designpattern.objectadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 * 源角色AbsAdaptee的子类
 */
class Adaptee1 extends AbstractAdaptee {

    @Override
    public void a() {
        System.out.println("Adaptee1: a()实现");
    }
}

Adaptee1的子类Adaptee1Sub:

package com.example.designpattern.objectadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 */
class Adaptee1Sub extends Adaptee1 {
    @Override
    public void a() {
        System.out.println("Adaptee1Sub: a()实现");
    }
}

源角色AbstractAdaptee的子类Adaptee2:

package com.example.designpattern.objectadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 * 源角色AbstractAdaptee的子类
 */
class Adaptee2 extends AbstractAdaptee {

    @Override
    public void a() {
        System.out.println("Adaptee2: a()实现");
    }
}

适配器角色:

package com.example.designpattern.objectadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 * 适配器角色:把源角色转换为目标接口、核心类
 * <p>
 * 需要AbsAdaptee及其所有子类
 */
class Adapter implements ITarget {
    /**
     * 源角色的对象引用
     */
    private AbstractAdaptee abstractAdaptee;

    public Adapter(AbstractAdaptee abstractAdaptee) {
        this.abstractAdaptee = abstractAdaptee;
    }

    @Override
    public void a() {
        abstractAdaptee.a();
    }

    @Override
    public void b() {
        System.out.println("Adapter: b()实现");
    }
}

调用:

package com.example.designpattern.objectadapter;

/**
 * @author Administrator
 * @date 2020/7/27
 */
class Client {
    public static void main(String[] args) {
        ITarget iTarget = new Adapter(new Adaptee1());
        iTarget.a();
        iTarget.b();

        System.out.println();

        ITarget iTarget2 = new Adapter(new Adaptee2());
        iTarget2.a();
        iTarget2.b();

        System.out.println();

        ITarget iTarget3 = new Adapter(new Adaptee1Sub());
        iTarget3.a();
        iTarget3.b();
    }
}

测试结果:
在这里插入图片描述

图7 对象适配器模式测试结果

6、PPT素材

在这里插入图片描述

PPT 01

在这里插入图片描述

PPT 02

在这里插入图片描述

PPT 03

在这里插入图片描述

PPT 04

在这里插入图片描述

PPT 05

在这里插入图片描述

PPT 06

在这里插入图片描述

PPT 07

在这里插入图片描述

PPT 08

在这里插入图片描述

PPT 09

在这里插入图片描述

PPT 10

在这里插入图片描述

PPT 11

在这里插入图片描述

PPT 12

在这里插入图片描述

PPT 13

在这里插入图片描述

PPT 14

在这里插入图片描述

PPT 15

微信公众号: TechU
在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值