当前位置: 首页 > news >正文

这是啥设计模式-适配模式

有一个广告召回系统,输入用户id就可以给用户推荐相应的广告,一开始我们只有布尔检索和向量检索两种方式。

1. 面向接口编程,而非实现

第一点就是定义接口,客户端关注的是接口,对客户端来说,他只关心检索引擎提供出来的接口是什么样子,不在意检索引擎是如何实现的。所以第一点就是抽象出接口。

class Recall {
public:virtual ~Recall() = default;virtual void recall(std::string uid) = 0;
};

2. 实现接口

我们有两个检索引擎,一个倒排,一个向量,根据接口分别实现这两种召回

// 倒排检索
class InvertRecall : public Recall {void recall(std::string uid) override {std::cout << uid << ": invert recall\n";}
};// 向量检索
class VectorRecall : public Recall {void recall(std::string uid) override {std::cout << uid << ": vector recall\n";}
};

3. 客户端调用

我们给客户端提供了两种召回方式,客户端其实并不关心的,他只关心接口是什么,通过这个接口他就可以拿到自己想要的结果

Recall* vectorRecall = new InvertRecall(); // 倒排召回
Recall* invertRecall = new VectorRecall(); // 向量召回
invertRecall->recall(uid);
vectorRecall->recall(uid);

我特意把名字写反了,就是为了表示客户端其实并不关心具体的召回方式是什么,谁来都一样,他只关心recall接口,根据recall接口就可以得到自己想要的结果,我们在改进一下

class AggRecall {
private:std::vector<std::shared_ptr<Recall>> m_recall;
public:void addRecall(const std::shared_ptr<Recall> &recall) {m_recall.emplace_back(recall);}void recall(std::string uid) {for (auto &recall: m_recall) {recall->recall(uid);}}
};

4. 新增了三方接口

除了我们自己实现的两种召回方式,还有一些其他的三方召回方式。当然,人家也很专业,也是面向接口编程,同时提供了一种实现方案。

// 三方代码勿动,以so方式提供
class ThirdPartyRecall {
public:virtual ~ThirdPartyRecall() = default;virtual void process(std::string uid, std::string thirdParty) = 0;
};class ThirdPartyRecallImp : public ThirdPartyRecall {
public:void process(std::string uid, std::string thirdParty) override {std::cout << thirdParty << " recall" << std::endl;}
};

这个时候客户端实现的AggRecall方案就要发生一些变化了,因此三方的接口名字和参数和我们实现的召回接口不一样,一种想当然的方式就是把所有召回引擎的接口统一,大家都叫recall,或者大家都叫process。

5. 统一接口

三方的召回接口是以so的方式提供的,我们想要修改代码也不现实了,一种愚蠢的方法就是修改自己的recall接口,但是你有没有想过,如果又有一个其他三方接口不一致怎么办呢?

// 三方代码勿动,以so方式提供
class GoogleRecall {
public:virtual ~GoogleRecall() = default;virtual void search(std::string uid) = 0;
};class GoogleRecallImp : public GoogleRecall {
public:void search(std::string uid) override {std::cout << uid << ": google search" << std::endl;}
};

6. 适配器

现在的问题就是如何把这些接口统一了,其实很简单,我们把三方的接口包一层不久可以了吗,或者说重命名不就可以了吗

class ThirdPartyAdapter : public Recall {
private:std::shared_ptr<ThirdPartyRecallImp> thirdPartyRecall;
public:explicit ThirdPartyAdapter(std::shared_ptr<ThirdPartyRecallImp> recall) : thirdPartyRecall(std::move(recall)) {}void recall(std::string uid) override {thirdPartyRecall->process(uid, "baidu");}
};

同样可以对其他的三方接口进行转换

class GoogleAdapter : public Recall {
private:std::shared_ptr<GoogleRecallImp> googleRecall;
public:explicit ThirdPartyAdapter(std::shared_ptr<GoogleRecallImp> recall) : googleRecall(std::move(recall)) {}void search(std::string uid) override {googleRecall->search(uid);}
};

就是这么简单,我们把process函数用一个recall函数包装起来,这样客户端在调用的时候依然调用的是recall函数,而且也继承了Recall接口

int main() {auto invertRecall = std::make_shared<InvertRecall>();auto vectorRecall = std::make_shared<VectorRecall>();auto thirdRecall = std::make_shared<ThirdPartyRecallImp>();auto googleRecall = std::make_shared<ThirdPartyAdapter>(thirdRecall);auto aggRecall = std::make_shared<AggRecall>();aggRecall->addRecall(invertRecall);aggRecall->addRecall(vectorRecall);aggRecall->addRecall(googleRecall);aggRecall->doRecall();
}

这个呢,就叫适配器,把其他接口转换成我们想要的接口。

相关文章:

这是啥设计模式-适配模式

有一个广告召回系统&#xff0c;输入用户id就可以给用户推荐相应的广告&#xff0c;一开始我们只有布尔检索和向量检索两种方式。 1. 面向接口编程&#xff0c;而非实现 第一点就是定义接口&#xff0c;客户端关注的是接口&#xff0c;对客户端来说&#xff0c;他只关心检索引…...

大语言模型(LLMs)Tokenizers详解

Tokenizers是大语言模型&#xff08;Large Language Models&#xff0c;LLMs&#xff09;中用于将文本分割成基本单元&#xff08;tokens&#xff09;的工具。这些工具不仅影响模型的输入表示&#xff0c;还直接影响模型的性能和效率。以下是对Tokenizers的详细解释&#xff1a…...

分支-快排/归并---1

目录 1.排序数组 2.数组中的第K个最大元素 3.最小k个数 4.排序数组&#xff08;归并&#xff09; 5.数组中的逆序对 6.计算右侧小于当前元素的个数 7. 翻转对 1.排序数组 快排的写法有很多&#xff0c;这里我采取了相对快的三路划分加随机基准值。 三路划分&#xff0c;是…...

代码随想录训练营 Day32打卡 动态规划 part01 理论基础 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯

代码随想录训练营 Day32打卡 动态规划 part01 一、 理论基础 动态规划中每一个状态一定是由上一个状态推导出来的&#xff0c;这一点就区分于贪心&#xff0c;贪心没有状态推导&#xff0c;而是从局部直接选最优的。 例如&#xff1a;有N件物品和一个最多能背重量为W 的背包…...

【智能流体力学】剖析ANSYS Fluent材料属性设定与边界条件

目录 一、材料属性设定**1. 材料属性的概述****功能****2. 材料属性的类型****标准材料库****多相流****燃烧模型****传热模型****辐射模型****3. 属性设置与函数****4. 自定义材料数据库****5. Granta数据库支持**二、边界条件**1. 通用边界条件****Pressure Inlet (压力-入口…...

微信小程序反编译工具

目录 介绍 工程结构还原 微信开发者工具运行 如何查看当前运行版本? 开启小程序F12 重新打包运行 效果示例 安装 用法 参数说明 获取微信小程序AppID 文件夹名即为AppID 下载地址 介绍 纯Golang实现,一个用于自动化反编译微信小程序的工具,小程序安全利器, 自…...

线程基本概念

一、进程的结束 wait(阻塞) 一般不做额外的事情 wait(非阻塞) 逻辑不受影响&#xff08;必须套在循环中&#xff09; wait作用&#xff1a;1.获取子进程退出状态 2.回收资源 传参为指针&#xff1a;被调修改主调 获取退出状态值&#xff1a; WIFEXITED 判断是否…...

在SpringBoot中执行后台任务

在 Spring Boot 中执行后台任务通常涉及到使用线程池和定时任务。Spring Boot 提供了多种方式来实现后台任务&#xff0c;包括使用 Scheduled 注解、ThreadPoolTaskExecutor 和 ExecutorService。 下面我将详细介绍如何使用这些方法来实现后台任务。 使用 Scheduled 注解 Sp…...

【网络】UDP回显服务器和客户端的构造,以及连接流程

回显服务器&#xff08;Echo Server&#xff09; 最简单的客户端服务器程序&#xff0c;不涉及到业务流程&#xff0c;只是对与 API 的用法做演示 客户端发送什么样的请求&#xff0c;服务器就返回什么样的响应&#xff0c;没有任何业务逻辑&#xff0c;没有进行任何计算或者…...

【智能流体力学】ANSYS Fluent工作流程设置、求解和后处理详解

目录 一、设置阶段1. **模型****功能** :**详细说明及原理** :2. **材料****功能** :**详细说明及原理** :3. **单元区域条件****功能** :**详细说明及原理** :4. **边界条件****功能** :**详细说明及原理** :5. **网格交界面****功能** :**详细说明及原理** :6. **动…...

最新UI六零导航系统源码 | 多模版全开源

六零导航页 (LyLme Spage) 致力于简洁高效无广告的上网导航和搜索入口&#xff0c;支持后台添加链接、自定义搜索引擎&#xff0c;沉淀最具价值链接&#xff0c;全站无商业推广&#xff0c;简约而不简单。 使用PHPMySql&#xff0c;增加后台管理 多模板选择&#xff0c;支持在…...

K8S中使用英伟达GPU —— 筑梦之路

前提条件 根据不同的操作系统&#xff0c;安装好显卡驱动&#xff0c;并能正常识别出来显卡&#xff0c;比如如下截图&#xff1a; GPU容器创建流程 containerd --> containerd-shim--> nvidia-container-runtime --> nvidia-container-runtime-hook --> libnvid…...

2024-2025年最值得选的Java计算机毕业设计选题大全:800个热门选题

一、前言 博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ…...

libnl教程(2):发送请求

文章目录 前言示例示例代码构造请求创建套接字发送请求 简化示例 前言 前置阅读要求&#xff1a;libnl教程(1):订阅内核的netlink广播通知 本文介绍&#xff0c;libnl如何向内核发送请求。这包含三个部分&#xff1a;构建请求&#xff1b;创建套接字&#xff1b;发送请求。 …...

【软件测试】功能测试理论基础

目录 项目的测试流程&#x1f3f4; 需求评审 评审形式 测试人员在需求评审中职责 测试计划与方案 测试计划 问题 测试方案&#x1f3f4; 测试计划与方案的对比 功能测试设计&#x1f3f4; 测试设计的步骤 项目的测试流程&#x1f3f4; 作用&#xff1a; 有序有效开展…...

玩机进阶教程-----回读 备份 导出分区来制作线刷包 回读分区的写入与否 修改xml脚本

很多工作室需要将修改好的系统导出来制作线刷包。前面分享过很多制作线刷包类的教程。那么一个机型中有很多分区。那些分区回读后要写入。那些分区不需要写入。强写有可能会导致不开机 不进系统的故障。首先要明白。就算机型全分区导出后在写回去 都不一定可以开机进系统。那么…...

MongoDB 插入文档

MongoDB 插入文档 MongoDB 是一个流行的 NoSQL 数据库,它使用文档存储数据。在 MongoDB 中,数据以 BSON(Binary JSON)格式存储,这是一种二进制表示的 JSON 格式。MongoDB 提供了灵活的数据模型,使得插入和查询文档变得非常简单。本文将详细介绍如何在 MongoDB 中插入文档…...

【内网】服务器升级nginx1.17.0

今天用rpm包升级内网nginx版本&#xff0c;上来就给我报错 警告&#xff1a;nginx-1.27.0-2.el7.ngx.x86_64.rpm: 头V4 RSA/SHA256 Signature, 密钥 ID 7bd9bf62: NOKEY 错误&#xff1a;依赖检测失败&#xff1a; libcrypto.so.10()(64bit) 被 nginx-1:1.27.0-2.el7.ngx.x…...

歌曲爬虫下载

本次编写一个程序要爬取歌曲音乐榜https://www.onenzb.com/ 里面歌曲。有帮到铁子的可以收藏和关注起来&#xff01;&#xff01;&#xff01;废话不多说直接上代码。 1 必要的包 import requests from lxml import html,etree from bs4 import BeautifulSoup import re impo…...

transformer-explainer

安装和启动 找到这个项目&#xff0c;然后装好了。 这个项目的目的如名字。 https://github.com/poloclub/transformer-explainerTransformer Explained: Learn How LLM Transformer Models Work with Interactive Visualization - poloclub/transformer-explainerhttps:/…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...