适配器模式

2023-04-03  本文已影响0人  长点点

安卓开发中适配器模式

一、什么是适配器模式

适配器模式是一种结构型设计模式,它可以将两个不兼容的接口转换成一个兼容的接口,使得原本不能一起工作的类可以协同工作。

适配器模式的主要角色有:

适配器模式有两种实现方式:

类适配器 对象适配器
通过继承被适配类,同时实现目标接口 通过持有被适配类的对象,同时实现目标接口
可以重写被适配类的方法,增加灵活性 不能重写被适配类的方法,只能调用原有的方法
耦合度高,只能继承一个被适配类,且要求目标接口必须是抽象类或接口 解耦了被适配类和目标接口,可以持有多个被适配类的对象,且不要求目标接口的类型

二、安卓源码中的实例

在安卓开发中,最常见的使用适配器模式的场景就是列表控件(如ListView、GridView等)和数据之间的绑定。列表控件需要展示不同类型和结构的数据,而数据又可以以数组、集合、数据库等形式存储。为了解决这个问题,安卓系统为我们提供了多种适配器类,它们都继承自BaseAdapter抽象类,实现了Adapter接口。

Adapter接口定义了列表控件和数据之间的通用方法,如:

BaseAdapter抽象类实现了Adapter接口,并提供了一些默认方法和通知数据变化的方法。它是所有具体适配器类的父类。

安卓系统为我们提供了以下几种常用的具体适配器类:

三、Kotlin、Java、C++实现并比较

为了比较不同语言实现适配器模式的不同之处,我们以一个简单的例子来说明。假设我们有一个电脑类(Computer),它有一个USB接口(UsbPort),可以连接一个USB设备(UsbDevice)。但是我们有一个PS/2键盘(Ps2Keyboard),它有一个PS/2接口(Ps2Port),无法直接连接到电脑上。为了解决这个问题,我们可以使用适配器模式,创建一个PS/2转USB的适配器(Ps2ToUsbAdapter),让键盘可以通过适配器连接到电脑上。

3.1 Kotlin实现

Kotlin是一种基于JVM的静态类型编程语言,它支持多范式,包括面向对象和函数式编程。它与Java有很高的互操作性,可以使用Java的类库和框架。

Kotlin可以使用类适配器或对象适配器来实现适配器模式。下面是类适配器的示例代码:

// 目标接口
interface UsbPort {
    fun connect()
}
// 适配者
interface Ps2Port {
    fun plugIn()
}
// 适配者实现类
class Ps2Keyboard : Ps2Port {
    override fun plugIn() {
        println("PS/2键盘已插入")
    }
}
// 类适配器,继承适配者并实现目标接口
class Ps2ToUsbAdapter : Ps2Keyboard(), UsbPort {
    override fun connect() {
        // 调用父类的plugIn方法
        super.plugIn()
        println("通过PS/2转USB适配器连接")
    }
}
// 客户端
class Computer {
    // 持有一个USB接口的引用
    var usbPort: UsbPort? = null

    // 连接USB设备的方法
    fun connectUsbDevice(usbDevice: UsbPort) {
        usbPort = usbDevice
        usbPort?.connect()
        println("电脑已连接USB设备")
    }
}

fun main() {
    // 创建一个电脑对象
    val computer = Computer()
    // 创建一个PS/2键盘对象
    val ps2Keyboard = Ps2Keyboard()
    // 创建一个PS/2转USB适配器对象,并传入PS/2键盘对象
    val adapter = Ps2ToUsbAdapter()
    // 通过适配器连接键盘和电脑
    computer.connectUsbDevice(adapter)
}

输出结果:

PS/2键盘已插入
通过PS/2转USB适配器连接
电脑已连接USB设备

可以看到,Kotlin实现适配器模式的优点有:

3.2 Java实现

Java也可以使用类适配器或对象适配器来实现适配器模式。下面是类适配器的示例代码:

// 目标接口
interface UsbPort {
    void connect();
}
// 适配者
interface Ps2Port {
    void plugIn();
}
// 适配者实现类
class Ps2Keyboard implements Ps2Port {
    @Override
    public void plugIn() {
        System.out.println("PS/2键盘已插入");
    }
}
// 类适配器,继承适配者并实现目标接口
class Ps2ToUsbAdapter extends Ps2Keyboard implements UsbPort {
    @Override
    public void connect() {
        // 调用父类的plugIn方法
        super.plugIn();
        System.out.println("通过PS/2转USB适配器连接");
    }
}
// 客户端
class Computer {
    // 持有一个USB接口的引用
    private UsbPort usbPort;

    // 连接USB设备的方法
    public void connectUsbDevice(UsbPort usbDevice) {
        usbPort = usbDevice;
        usbPort.connect();
        System.out.println("电脑已连接USB设备");
    }
}

public class Main {
    public static void main(String[] args) {
        // 创建一个电脑对象
        Computer computer = new Computer();
        // 创建一个PS/2键盘对象
        Ps2Keyboard ps2Keyboard = new Ps2Keyboard();
        // 创建一个PS/2转USB适配器对象,并传入PS/2键盘对象
        Ps2ToUsbAdapter adapter = new Ps2ToUsbAdapter();
        // 通过适配器连接键盘和电脑
        computer.connectUsbDevice(adapter);
    }
}

输出结果:

PS/2键盘已插入
通过PS/2转USB适配器连接
电脑已连接USB设备

可以看到,Java实现适配器模式的优点有:

Java实现适配器模式的缺点有:

3.3 C++实现

C++是一种编译型的编程语言,它支持多范式,包括面向对象、泛型、元编程等特性。它是一种高效和灵活的语言,广泛应用于系统开发和游戏开发等领域。

C++也可以使用类适配器或对象适配器来实现适配器模式。下面是类适配器的示例代码:

#include <iostream>
using namespace std;

// 目标接口
class UsbPort {
public:
    virtual void connect() = 0;
};

// 适配者
class Ps2Port {
public:
    virtual void plugIn() = 0;
};

// 适配者实现类
class Ps2Keyboard : public Ps2Port {
public:
    void plugIn() override {
        cout << "PS/2键盘已插入" << endl;
    }
};

// 类适配器,继承适配者并实好的,接下来是第三部分的内容的续篇:

```cpp
现目标接口
class Ps2ToUsbAdapter : public Ps2Keyboard, public UsbPort {
public:
    void connect() override {
        // 调用父类的plugIn方法
        Ps2Keyboard::plugIn();
        cout << "通过PS/2转USB适配器连接" << endl;
    }
};

// 客户端
class Computer {
private:
    // 持有一个USB接口的指针
    UsbPort* usbPort;
public:
    // 连接USB设备的方法
    void connectUsbDevice(UsbPort* usbDevice) {
        usbPort = usbDevice;
        usbPort->connect();
        cout << "电脑已连接USB设备" << endl;
    }
};

int main() {
    // 创建一个电脑对象
    Computer computer;
    // 创建一个PS/2键盘对象
    Ps2Keyboard ps2Keyboard;
    // 创建一个PS/2转USB适配器对象,并传入PS/2键盘对象
    Ps2ToUsbAdapter adapter;
    // 通过适配器连接键盘和电脑
    computer.connectUsbDevice(&adapter);
    return 0;
}

输出结果:

PS/2键盘已插入
通过PS/2转USB适配器连接
电脑已连接USB设备

可以看到,C++实现适配器模式的优点有:

C++实现适配器模式的缺点有:

四、适配器模式的优缺点和使用场景

适配器模式的优点有:

适配器模式的缺点有:

适配器模式适用于以下场景:

五、适配器模式的优化方向

适配器模式的优化方法有以下几点:

六、适配器模式和其他设计模式的比较

设计模式 优点 缺点 使用场景
适配器模式 可以让不兼容的接口能够协同工作,提高了代码的复用性和灵活性。 会增加系统的复杂度,让代码的理解和维护更困难。 需要将一个类的接口转换为另一个接口的场景,例如不同系统之间的数据交换,不同类库之间的功能调用等。
代理模式 可以对被代理对象进行控制和增强,实现了对象之间的解耦。 会增加系统的开销,引入更多的类和对象。 需要控制对某个对象的访问或者添加一些额外的操作的场景,例如远程代理,虚拟代理,保护代理等。
装饰器模式 可以动态地给对象增加一些职责,扩展对象的功能,而不影响原有对象的结构。 会产生很多的装饰类小对象和装饰组合策略,增加系统复杂度,增加代码的阅读理解成本。 需要在不改变原有对象结构的情况下,动态地给一个对象增加一些新的功能或者增强一些已有的功能的场景,例如给窗口添加滚动条,给文本添加格式等。
上一篇 下一篇

猜你喜欢

热点阅读