设计模式Python版 适配器模式

文章目录


前言

GOF设计模式分三大类:

  • 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。
  • 结构型模式:关注类和对象之间的组合,包括适配器模式、桥接模式、组合模式、装饰模式、外观模式、享元模式和代理模式。
  • 行为型模式:关注对象之间的交互,包括职责链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。

一、适配器模式

适配器模式(Adapter Pattern)

  • 定义:将一个接口转换成客户希望 的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。

  • 解决问题:如何在不修改现有系统的前提下重用没有源码的第三方类库?

  • 使用场景:

    • 适配器模式通常用于现有系统与第三方产品功能的集成,采用增加适配器的方式将第三方类集成到系统中。
    • 当你希望使用一个已经存在的类,但其接口(例如方法名)不符合你的需求时。
    • 当你想要创建一个可重用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
    • 当你需要使用多个现有的子类,但又不想派生所有这些子类的适配器时,可以采用对象适配器,从而可以复用现有的子类。
  • 组成:

    • 目标(Target)接口/类:当前系统期望使用的接口,它定义了客户希望使用的方法。
    • 适配器(Adapter)类:一个中介类,它实现了目标接口,并通过私有方式包含一个被适配者的实例,从而将目标接口和被适配者接口匹配起来。
    • (被)适配者(Adaptee)类:一个现存的需要适配的类,它包含一些功能,但是不符合目标接口。
  • 优点:

    • 将目标类和适配者类解耦。通过引入一个适配器类来重用现有的适配者类,无须修改原有结构。
    • 增加了类的透明性和复用性。将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者类的复用性,同一个适配者类可以在多个不同的系统中复用。

二、适配器模式实现

实现方法一:对象适配器模式

  • 在对象适配器模式(使用频率更高)中,适配器与适配者之间是关联关系

  • 对象适配器模式结构图

对象适配器模式示例

使用适配器模式来重用算法库中的QuickSort和BinarySearch算法

python 复制代码
# 模块adapters.py
"""目标"""


class ScoreOperation:
    """抽象成绩操作类:目标接口"""

    def sort(self, scores: list[int]) -> list[int]:
        raise NotImplementedError

    def search(self, scores: list[int], key: int) -> int:
        raise NotImplementedError


"""适配器"""


class OperationAdapter(ScoreOperation):
    def __init__(self):
        self.sort_obj = QuickSort()  # 被适配者对象
        self.search_obj = BinarySearch()  # 被适配者对象

    def sort(self, scores):
        return self.sort_obj.quick_sort(scores)  # 调用被适配者方法

    def search(self, scores, key):
        return self.search_obj.binary_search(scores, key)  # 调用被适配者方法


"""被适配者"""


class QuickSort:
    def quick_sort(self, data: list[int]):
        # 快速排序算法(略)
        return sorted(data)


class BinarySearch:
    def binary_search(self, data: list[int], key: int):
        # 二分查找算法(略)
        return data.index(key) if key in data else None

引入配置文件config.json

json 复制代码
{
    "class_name": "OperationAdapter"
}

工具类JsonUtil

python 复制代码
# 模块 utils.py
from pathlib import Path
import json


class JsonUtil:
    @staticmethod
    def get_class_name():
        """读取配置文件,返回配置文件中的配置"""
        path = Path("config.json")
        contents = path.read_text(encoding="utf-8")
        conf = json.loads(contents)
        return conf.get("class_name", None)

客户端代码

  • 通过引入配置文件和反射机制,可以在不修改客户端代码的情况下使用新的适配器,无须修改源代码,符合开闭原则。
python 复制代码
import adapters
from utils import JsonUtil

class_name = JsonUtil.get_class_name()
klass = getattr(adapters, class_name, None)
if klass is None:
    raise ValueError

operation: adapters.ScoreOperation = klass()
scores = [92, 98, 91, 100, 85, 80]
result = operation.sort(scores)
print(f"成绩排序结果:{result}")

print("查找成绩90:", end="")
if operation.search(result, 90):
    print("找到成绩90。")
else:
    print("没有找到成绩90。")

print("查找成绩92:", end="")
if operation.search(result, 92):
    print("找到成绩92。")
else:
    print("没有找到成绩92。")

输出结果

sh 复制代码
成绩排序结果:[80, 85, 91, 92, 98, 100]
查找成绩90:没有找到成绩90。
查找成绩92:找到成绩92。

实现方式二:类适配器模式

  • 在类适配器模式中,适配器与适配者之间是继承(或实现) 关系
  • 类适配器模式结构图

实现方式三:双向适配器模式

  • 在适配器中同时包含对目标类和适配者类的引用,适配者可以通过它调用目标类中的方法,目标类也可以通过它调用适配者类中的方法,那么该适配器就是一个双向适配器。
  • 双向适配器模式结构图

三、适配器模式在Django中的应用

Django缓存框架设计理念:缓存 API 应该为不同的缓存后端提供一致的接口。Django 提供了多种缓存后端的支持,如本地内存、文件、数据库、Memcached 或 Redis 等。为了能够使用不同的缓存后端,Django 实现了缓存适配器,这些适配器为不同的缓存系统提供了统一的接口。

python 复制代码
# 底层缓存API示例
from django.core.cache import cache

# cache.set(key, value, timeout=DEFAULT_TIMEOUT, version=None)
cache.set('my_key', 'hello, world!', 30)

# cache.get(key, default=None, version=None)
cache.get('my_key')

参考资料:Django缓存框架


您正在阅读的是《设计模式Python版》专栏!关注不迷路~

相关推荐
QQ274378510912 分钟前
基于python热门歌曲采集分析系统
开发语言·python
qq40542519717 分钟前
基于python的体育新闻数据可视化及分析
开发语言·python·信息可视化
想成为配环境大佬18 分钟前
流式学习(简易版)
python·学习·信息可视化
belldeep1 小时前
python:如何播放 .spx 声音文件
python·ffmpeg·pyaudio
荣--3 小时前
C++学习:CRTP 模式是什么
c++·设计模式·模板类
张焚雪3 小时前
关于图像锐化的一份介绍
开发语言·python·opencv·计算机视觉
CodeClimb3 小时前
【华为OD-E卷 - 任务最优调度 100分(python、java、c++、js、c)】
java·javascript·c++·python·华为od
虞书欣的63 小时前
Python小游戏29乒乓球
python·游戏·小程序·pygame
MichaelIp3 小时前
大模型高级工程师实践 - 将课程内容转为视频
人工智能·python·自然语言处理·langchain·prompt·aigc·音视频