设计模式Python版 适配器模式

embedded/2025/2/3 21:46:03/

文章目录


前言

GOF设计模式分三大类:

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

一、适配器模式

适配器模式(Adapter Pattern)

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

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

  • 使用场景:

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

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

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

二、适配器模式实现

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

在这里插入图片描述

对象适配器模式示例

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

python"># 模块adapters.py
"""目标"""class ScoreOperation:"""抽象成绩操作类:目标接口"""def sort(self, scores: list[int]) -> list[int]:raise NotImplementedErrordef 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

{"class_name": "OperationAdapter"
}

工具类JsonUtil

python"># 模块 utils.py
from pathlib import Path
import jsonclass JsonUtil:@staticmethoddef 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 JsonUtilclass_name = JsonUtil.get_class_name()
klass = getattr(adapters, class_name, None)
if klass is None:raise ValueErroroperation: 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。")

输出结果

成绩排序结果:[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版》专栏!关注不迷路~


http://www.ppmy.cn/embedded/159278.html

相关文章

游戏引擎介绍:Game Engine

简介 定义:软件框架,一系列为开发游戏的工具的集合 可协作创意生产工具,复杂性艺术,注重realtime实时 目的 为艺术家,设计师,程序员设计工具链 游戏引擎开发参考书 推荐:Game Engine Archite…

JAVA安全—反射机制攻击链类对象成员变量方法构造方法

前言 还是JAVA安全,哎,真的讲不完,太多啦。 今天主要是讲一下JAVA中的反射机制,因为反序列化的利用基本都是要用到这个反射机制,还有一些攻击链条的构造,也会用到,所以就讲一下。 什么是反射…

通过Redisson构建延时队列并实现注解式消费

目录 一、序言二、延迟队列实现1、Redisson延时消息监听注解和消息体2、Redisson延时消息发布器3、Redisson延时消息监听处理器 三、测试用例四、结语 一、序言 两个月前接了一个4万的私活,做一个线上商城小程序,在交易过程中不可避免的一个问题就是用户…

Vue 响应式渲染 - 列表布局和v-html

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue 响应式渲染 - 列表布局和v-html 目录 列表布局 简单渲染列表 显示索引值 点击变色 V-html 作用 注意 采用策略 应用 总结 列表布局 简单渲染列表 Data中设置状态,是一个数组格式的默认信息。 然后…

AAPM:基于大型语言模型代理的资产定价模型,夏普比率提高9.6%

“AAPM: Large Language Model Agent-based Asset Pricing Models” 论文地址:https://arxiv.org/pdf/2409.17266v1 Github地址:https://github.com/chengjunyan1/AAPM 摘要 这篇文章介绍了一种利用LLM代理的资产定价模型(AAPM)…

计算机网络 应用层 笔记1(C/S模型,P2P模型,FTP协议)

应用层概述: 功能: 常见协议 应用层与其他层的关系 网络应用模型 C/S模型: 优点 缺点 P2P模型: 优点 缺点 DNS系统: 基本功能 系统架构 域名空间: DNS 服务器 根服务器: 顶级域…

LeetCode - #196 删除重复的电子邮件并保留最小 ID 的唯一电子邮件

网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…

【C++篇】哈希表

目录 一,哈希概念 1.1,直接定址法 1.2,哈希冲突 1.3,负载因子 二,哈希函数 2.1,除法散列法 /除留余数法 2.2,乘法散列法 2.3,全域散列法 三,处理哈希冲突 3.1&…