Go语言必知必会100问题-06 生产者端接口

生产者端接口

Go语言必知必会100问题-05 接口污染中介绍了程序中使用接口是有价值的。在编码的时候,接口应该放在哪里呢?这是Go开发人员经常有误解的一个问题,本文将深入分析该问题。

在深入探讨问题之前,先对提及的术语做一个定义说明,确保我们对其有清晰的理解。

  • 生产者端:接口定义与具体实现在同一个包中,称这种为生产者端接口。像下图所示,接口的定义和具体实现都在foo包中,调用客户端代码在bar包中。

在这里插入图片描述

  • 消费者端:接口定义与具体实现不在相同的包中,而是定义在调用的客户端代码所在的包中,称这种为消费者端接口。如下图所示,接口定义在使用方包bar中。

在这里插入图片描述

在生产者端定义接口,与具体实现放在一起,这是具有C#或Java背景语言的人惯用写法。然而,在Go语言中,在大多数情况下,我们不应该采用这种写法。下面通过一个示例进行说明。

示例中,我们创建一个特定的包来存储和查询客户数据。同时在该包中定义一个接口,所有对客户数据的操作都通过接口来实现。对应到前面,这种实现就是生产者端接口。

package store

type CustomerStorage interface {
        StoreCustomer(customer Customer) error
        GetCustomer(id string) (Customer, error)
        UpdateCustomer(customer Customer) error
        GetAllCustomers() ([]Customer, error)
        GetCustomersWithoutContract() ([]Customer, error)
        GetCustomersWithNegativeBalance() ([]Customer, error)
}

对于上面在生产者端创建接口,并对外暴露这个接口。可能认为有很好的理由这样做,我们可能会说,1.这样可以将客户端代码与实际实现分离,2. 在测试的时候,调用方很方便Mock一个假的接口实现进行测试。但是,这不是Go中的最佳实践。

正如Go语言必知必会100问题-05 接口污染所提到的,与具有显示实现接口的语言相比,Go中通过隐式实现接口,这会带来一些变化,像其它语言惯用的生产者端接口在Go语言中并不是最佳实践。在大多数情况下,应该遵循Go语言必知必会100问题-05 接口污染提到的原则:应该发现抽象而不是创建抽象。这意味着生产者不能为所有客户端强制一个给定的抽象。相反,由客户端决定它是否需要某种形式的抽象。然后确定最适合它需要的抽象级别。

对于上述示例,也许客户端A不会对解耦它的代码感兴趣,也许客户端B想要解耦它的代码,但只对 GetAllCustomers 方法感兴趣。在这种情况下,可以使用单个方法创建一个接口,引用外部包中的 Customer 结构体。

package client

type customersGetter interface {
        GetAllCustomers() ([]store.Customer, error)
}

从包组织引用关系来看,客户端和存储两个包关系如下图。需要注意几点:

  • 由于 customersGetter 接口仅在客户端包中使用,因此该接口可以保持不导出。
  • 咋一看,下图看起来像存在循环依赖。但是,由于隐式满足接口,存储与客户端之间没有循环依赖关系。这也是为什么这种方法在具有显示实现的语言中并不总是可行的原因。

在这里插入图片描述

采用在客户端中定义接口的关键点是客户端可以根据需要定义最准确的抽象(像customersGetter只有一个方法),契合接口隔离原则(SOLID中的I),该原则指出不应强迫任何客户端依赖它不使用的方法。因此,在这种情况下,最好的方法是在生产者端公开具体实现(方法可导出),让客户端决定如何使用它以及是否需要抽象。

本文提到了生产者端接口和消费者端接口两个概念,前面分析了消费者端接口,为了完整性,这里对生产者端接口也做点分析。生产者端接口有时候会在标准库中遇到,例如encoding子包中定义了实现的接口,如encoding/json、encoding/binary. 采用这种方式错了吗?前面不是说Go中不推荐生产者端接口吗? 没有错,在这种情况下,encoding包中定义的抽象在标准库中使用,语言设计者知道预先创建这种抽象是有价值的。这满足Go语言必知必会100问题-05 接口污染中的讨论:如果你认为抽象在想象的将来可能有用,但是不能证明这个抽象时有效的,就不要创建抽象。

因此,在大多数情况下,Go语言中的接口应该位于消费者端。但是,在特定情况下,例如,当我们知道(不是预想)抽象对消费者有帮助时,我们可能希望将其放在生产者端。如果要这样做,应该努力让接口尽可能地最小化(接口中的方法仅可能少),像encoding/json中定义的Marshaler接口只包含1个方法,这样增加它的可重用潜力并使其更容易组合。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/411688.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年老薛主机开工大吉活动:云服务器5折起,续费同价!

2024年老薛主机开工大吉活动开始了,香港/美国云服务器季付7折,半年付6折,年付5折,续费同价! 活动地址: 点此直达老薛主机官网 活动详情: 老薛主机2024开年促销活动,香港/美国云服…

全网最全AI绘画工具汇总(二)

一.AI绘画 图像 创造人工智能艺术的方式共有多种方法,包括使用数字模式的程序“基于规则”的图像生成、模拟笔触和其他绘画效果的算法,以及人工智能或深度学习算法等。 最早的重要人工智能艺术系统之一是AARON,由哈罗德科恩于1960年代末开…

Pytorch添加自定义算子之(1)-安装配置Eigen库

一、安装对应的ubuntu环境 推荐使用Docker FROM nvcr.io/nvidia/pytorch:23.01-py3 RUN pip install tensorboardX RUN pip install pyyaml RUN pip install yacs RUN pip install termcolor RUN pip install opencv-python RUN pip install timm0.6.12 WORKDIR /app COPY . …

【LeetCode:2476. 二叉搜索树最近节点查询 + 中序遍历 + 有序表】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

vDPA测试环境搭建

要求: 运行 Linux 发行版的计算机。本指南使用 CentOS 9-stream,但对于其他 Linux 发行版,特别是对于 Red Hat Enterprise Linux 7,命令不应有重大变化。 具有 sudo 权限的用户 ~ 主目录中有 25 GB 的可用空间 至少 8GB 内存 …

蓝桥杯-扫雷

代码解答及思路: #include <iostream> using namespace std; int main() { int n,m; int a[100][100] {0},b[100][100];//记住要开数组确数 &#xff0c;这样外围就会有边 &#xff0c;不能直接设置值&#xff0c;要记住&#xff01;&#xff01;&#xff01;&#…

FairyGUI × Cocos Creator 3.x 场景切换

前言 前文提要&#xff1a; FariyGUI Cocos Creator 入门 FairyGUI Cocos Creator 3.x 使用方式 个人demo&#xff1a;https://gitcode.net/qq_36286039/fgui_cocos_demo_dust 个人demo可能会更新其他代码&#xff0c;还请读者阅读本文内容&#xff0c;自行理解并实现。 官…

模版(初级)

一.泛型编程 当我们要写一个交换函数时&#xff0c;面对不同的类型&#xff0c;我们可能就需要向如下这么写&#xff1a; void Swap(int& left, int& right) {int temp left;left right;right temp; }void Swap(double& left, double& right) {double tem…

【linux】常见指令 -通配符,数据管道,重定向,压缩打包...

目录 前言 基本指令 ls命令 常见选项 ​编辑 pwd命令 cd 指令 常见选项 touch指令 mkdir指令 常见选项 rm 指令 常见选项 man指令 cp指令 常用选项&#xff1a; mv指令 常用选项 nano指令 如何写入且执行文件&#xff1f; cat指令 常用选项 more指令…

RPA超级自动化、AIGC大模型、低代码、流程挖掘四大热门峰会火热报名中!

由企智未来科技&#xff08;RPA中国、LowCode低码时代、AIGC开放社区&#xff09;主办的第四届「ISIG中国产业智能大会」将于2024年3月16日在上海召开&#xff0c;本届主题为“与科技共赢&#xff0c;与产业共进”。在此次大会中&#xff0c;我们将设立RPA超自动化、低代码/零代…

【零代码研发】OpenCV实验大师工作流引擎C++ SDK演示

学习《OpenCV应用开发&#xff1a;入门、进阶与工程化实践》一书 做真正的OpenCV开发者&#xff0c;从入门到入职&#xff0c;一步到位&#xff01; OpenCV开发痛点 传统图像算法开发最好的开源解决方案是OpenCV视觉库&#xff0c;但是OpenCV中收录了2000的传统算法&#xf…

鸿蒙 渲染控制

前提&#xff1a;基于官网3.1/4.0文档。参考官网文档 基于Android开发体系来进行比较和思考。&#xff08;或有偏颇&#xff0c;自行斟酌&#xff09; 1.概念 ArkUI通过自定义组件的build()函数和builder装饰器中的声明式UI描述语句构建相应的UI。在声明式描述语句中开发者除了…

Linux笔记--硬链接与软链接

一、硬链接 1.inode和block 文件包含两部分数据&#xff1a;文件属性和实际内容&#xff0c;属性放在inode中&#xff0c;实际内容放在data block中。还有个超级区块&#xff08;superblock&#xff09;记录整个文件系统的整体信息&#xff0c;包括inode和block的总量&#x…

基于huggingface加载openai/clip-vit-large-patch14-336视觉模型demo

文章目录 引言一、模型加载二、huggingface梯度更新使用三、图像处理四、模型推理五、整体代码总结 引言 本文介绍如何使用huggingface加载视觉模型openai/clip-vit-large-patch14-336&#xff0c;我之所以记录此方法源于现有大模型基本采用huggingface库来加载视觉模型和大语…

【办公类-22-10】周计划系列(5-2)“周计划-02源文件docx读取5天“ (2024年调整版本)

背景需求 承接上文&#xff0c;继续制作周计划 【办公类-22-09】周计划系列&#xff08;5-1&#xff09;“周计划-01源文件统一名称“ &#xff08;2024年调整版本&#xff09;-CSDN博客文章浏览阅读76次。【办公类-22-09】周计划系列&#xff08;5-1&#xff09;“周计划-01…

LabVIEW燃料电池船舶电力推进监控系统

LabVIEW燃料电池船舶电力推进监控系统 随着全球经济一体化的推进&#xff0c;航运业的发展显得尤为重要&#xff0c;大约80%的世界贸易依靠海上运输实现。传统的船舶推进系统主要依赖于柴油机&#xff0c;这不仅耗能高&#xff0c;而且排放严重&#xff0c;对资源和环境的影响…

2.25 day5 QT

闹钟 .h代码 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimerEvent> #include <QTime> #include <QTextToSpeech>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJ…

【Linux操作系统】死锁 | 预防、避免死锁

创作不易&#xff0c;本篇文章如果帮助到了你&#xff0c;还请点赞 关注支持一下♡>&#x16966;<)!! 主页专栏有更多知识&#xff0c;如有疑问欢迎大家指正讨论&#xff0c;共同进步&#xff01; &#x1f525;Linux系列专栏&#xff1a;Linux基础 &#x1f525; 给大家…

Codeforces Round 881 (Div. 3) F2. Omsk Metro (hard version)(倍增+最大子段和)

原题链接&#xff1a;F2. Omsk Metro (hard version) 题目大意&#xff1a; 最初开始时&#xff0c;你有一个根节点 1 1 1 且权值为 1 1 1 。 接下来会有 n n n 个操作&#xff0c;每次操作按照如下格式给出&#xff1a; 设操作开始前节点总数为 c n t cnt cnt&#xff1…

小型内衣裤洗衣机哪个牌子好?四大顶尖内衣洗衣机测评分享

要知道&#xff0c;内衣裤可能会残留我们身体分泌的尿液&#xff0c;或者是没有擦干净的便便&#xff0c;以及其他的一些分泌物&#xff0c;据科学家研究发现&#xff0c;内衣裤是含有很多细菌和病毒的地方&#xff0c;如果将内衣裤和衣服放在一起洗&#xff0c;导致这些细菌附…