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

Go 依赖注入设计模式


💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
在这里插入图片描述

  • 推荐:「stormsha的主页」👈,持续学习,不断总结,共同进步,为了踏实,做好当下事儿~

  • 专栏导航

    • Python系列: Python面试题合集,剑指大厂
    • Git系列: Git操作技巧
    • GO系列: 记录博主学习GO语言的笔记,该笔记专栏尽量写的试用所有入门GO语言的初学者
    • 数据库系列: 详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 运维系列: 总结好用的命令,高效开发
    • 算法与数据结构系列: 总结数据结构和算法,不同类型针对性训练,提升编程思维

    非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

    💖The Start💖点点关注,收藏不迷路💖

    📒文章目录

      • 依赖注入的基本概念
      • Go 语言中实现依赖注入的挑战
      • 手动实现依赖注入
      • 使用反射进行依赖注入
      • 使用第三方库
        • 使用 Wire
        • 使用 Dig
      • 总结


内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容
在软件开发中,依赖注入(Dependency Injection, DI)是一种设计模式,它允许开发者将依赖关系从组件中解耦出来,从而提高代码的模块化和可测试性。Go 语言以其简洁和高效著称,但原生并不支持依赖注入。然而,这并没有阻止开发者在 Go 中实现依赖注入。本文将探讨在 Go 中实现依赖注入的一些技巧

依赖注入的基本概念

在深入讨论 Go 中的实现技巧之前,我们先简要回顾一下依赖注入的基本概念。依赖注入是一种编程模式,它允许开发者将组件所需的依赖项以参数的形式传递给组件,而不是让组件自己创建或查找这些依赖项。这通常通过构造函数、方法调用或属性赋值实现。

Go 语言中实现依赖注入的挑战

Go 语言的类型系统和编译时特性使得它在某些方面不适合原生实现依赖注入。例如,Go 没有接口默认方法,这限制了依赖注入框架的灵活性。此外,Go 的编译器不会自动处理依赖项的注入,这意味着开发者需要手动管理依赖关系。

手动实现依赖注入

尽管 Go 没有原生支持,但开发者可以通过手动方式实现依赖注入。以下是一种简单的手动实现方法:

  1. 定义接口:首先定义一个接口来描述依赖项的行为。
  2. 实现接口:为不同的依赖项提供具体的实现。
  3. 构造函数注入:在组件的构造函数中接受依赖项作为参数。
package mainimport "fmt"// 定义一个数据库操作的接口
type Database interface {Query(query string) string
}// 实现数据库接口
type MySQL struct{}func (m *MySQL) Query(query string) string {return fmt.Sprintf("Executing query on MySQL: %s", query)
}// 需要数据库依赖的组件
type DataProcessor struct {db Database
}func NewDataProcessor(db Database) *DataProcessor {return &DataProcessor{db: db}
}func main() {db := &MySQL{}processor := NewDataProcessor(db)fmt.Println(processor.db.Query("SELECT * FROM users"))
}

使用反射进行依赖注入

Go 的 reflect 包提供了一种在运行时检查和调用类型信息的能力。利用反射,我们可以在一定程度上实现依赖注入:

  1. 使用标签:在结构体字段上使用标签来指定依赖项。
  2. 反射注入:通过反射遍历结构体的字段,并根据标签注入依赖项。
package mainimport ("fmt""reflect"
)type DependencyInjector struct {dependencies map[string]interface{}
}func NewDependencyInjector() *DependencyInjector {return &DependencyInjector{dependencies: make(map[string]interface{}),}
}func (di *DependencyInjector) Provide(name string, dependency interface{}) {di.dependencies[name] = dependency
}func (di *DependencyInjector) Inject(target interface{}) {t := reflect.TypeOf(target)v := reflect.ValueOf(target)for i := 0; i < t.NumField(); i++ {field := t.Field(i)depName := field.Tag.Get("inject")if depName != "" {if dep, ok := di.dependencies[depName]; ok {fieldValue := v.Elem().Field(i)fieldValue.Set(reflect.ValueOf(dep))}}}
}// 示例使用
type Service struct {DB Database `inject:"db"`
}func main() {injector := NewDependencyInjector()injector.Provide("db", &MySQL{})service := Service{}injector.Inject(&service)fmt.Println(service.DB.Query("SELECT * FROM users"))
}

使用第三方库

虽然手动实现和反射方法可以工作,但它们可能不够灵活或效率低下。幸运的是,有第三方库可以帮助我们在 Go 中实现依赖注入,例如 wiredig

  1. Wire:一个代码生成工具,它分析代码并生成所需的注入代码。
  2. Dig:一个轻量级的依赖注入容器,它使用标签来管理依赖关系。

使用 Wire

Wire 通过分析 Go 代码中的构造函数来自动生成依赖注入的代码。使用 Wire,你只需要定义你的组件和它们的依赖关系,然后 Wire 会生成一个 wire_gen.go 文件,其中包含了所有必要的注入逻辑。

使用 Dig

Dig 是一个更现代的依赖注入库,它使用 Go 的标签系统来识别和注入依赖项。Dig 允许你定义依赖项的生命周期,并提供了一个简单的 API 来管理依赖项的注入。

总结

依赖注入是一种强大的设计模式,可以帮助开发者编写更干净、更模块化的代码。虽然 Go 语言没有原生支持依赖注入,但通过手动实现、使用反射或利用第三方库,我们仍然可以在 Go 中有效地使用这一模式。选择哪种方法取决于你的具体需求和偏好,但无论如何,依赖注入都是提升 Go 开发效率的一个有力工具。


🔥🔥🔥道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

💖The End💖点点关注,收藏不迷路💖

相关文章:

Go 依赖注入设计模式

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

使用React复刻ThreeJS官网示例——keyframes动画

最近在看three.js相关的东西&#xff0c;想着学习一下threejs给的examples。源码是用html结合js写的&#xff0c;恰好最近也在学习react&#xff0c;就用react框架学习一下。 本文参考的是threeJs给的第一个示例 three.js examples (threejs.org) 一、下载threeJS源码 通常我们…...

嵌入式linux面试1

1. linux 1.1. Window系统和Linux系统的区别 linux区分大小写windows在dos&#xff08;磁盘操作系统&#xff09;界面命令下不区分大小写&#xff1b; 1.2. 文件格式区分 windows用扩展名区分文件&#xff1b;如.exe代表执行文件&#xff0c;.txt代表文本文件&#xff0c;.…...

智能交通(3)——Learning Phase Competition for Traffic Signal Control

论文分享 https://dl.acm.org/doi/pdf/10.1145/3357384.3357900https://dl.acm.org/doi/pdf/10.1145/3357384.3357900 论文代码 https://github.com/gjzheng93/frap-pubhttps://github.com/gjzheng93/frap-pub 摘要 越来越多可用的城市数据和先进的学习技术使人们能够提…...

【扩散模型】LCM LoRA:一个通用的Stable Diffusion加速模块

潜在一致性模型&#xff1a;[2310.04378] Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference (arxiv.org) 原文&#xff1a;Paper page - Latent Consistency Models: Synthesizing High-Resolution Images with Few-Step Inference (…...

【PYG】pytorch中size和shape有什么不同

一般使用tensor.shape打印维度信息&#xff0c;因为简单直接 在 PyTorch 中&#xff0c;size 和 shape 都用于获取张量的维度信息&#xff0c;但它们之间有细微的区别。下面是它们的定义和用法&#xff1a; size&#xff1a; size 是一个方法&#xff08;size()&#xff09;和…...

备份服务器出错怎么办?

在企业的日常运营中&#xff0c;备份服务器扮演着至关重要的角色&#xff0c;它确保了数据的安全和业务的连续性。然而&#xff0c;备份服务器也可能遇到各种问题&#xff0c;如备份失败、数据损坏或备份系统故障等。这些问题可能导致数据丢失或业务中断&#xff0c;给企业带来…...

数据库(表)

要求如下&#xff1a; 一&#xff1a;数据库 1&#xff0c;登录数据库 mysql -uroot -p123123 2&#xff0c;创建数据库zoo create database zoo; Query OK, 1 row affected (0.01 sec) 3&#xff0c;修改字符集 mysql> use zoo;---先进入数据库zoo Database changed …...

Feign-未完成

Feign Java中如何实现接口调用&#xff1f;即如何发起http请求 前三种方式比较麻烦&#xff0c;在发起请求前&#xff0c;需要将Java对象进行序列化转为json格式的数据&#xff0c;才能发送&#xff0c;然后进行响应时&#xff0c;还需要把json数据进行反序列化成java对象。 …...

# [0705] Task06 DDPG 算法、PPO 算法、SAC 算法【理论 only】

easy-rl PDF版本 笔记整理 P5、P10 - P12 joyrl 比对 补充 P11 - P13 OpenAI 文档整理 ⭐ https://spinningup.openai.com/en/latest/index.html 最新版PDF下载 地址&#xff1a;https://github.com/datawhalechina/easy-rl/releases 国内地址(推荐国内读者使用)&#xff1a; 链…...

Open3D 点云CPD算法配准(粗配准)

目录 一、概述 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2配准后点云 一、概述 在Open3D中&#xff0c;CPD&#xff08;Coherent Point Drift&#xff0c;一致性点漂移&#xff09;算法是一种经典的点云配准方法&#xff0c;适用于无序点云的非…...

04-ArcGIS For JavaScript的可视域分析功能

文章目录 综述代码实现代码解析结果 综述 在数字孪生或者实景三维的项目中&#xff0c;视频融合和可视域分析&#xff0c;一直都是热点问题。Cesium中&#xff0c;支持对阴影的后处理操作&#xff0c;通过重新编写GLSL代码就能实现视域和视频融合的功能。ArcGIS之前支持的可视…...

Nestjs基础

一、创建项目 1、创建 安装 Nest CLI&#xff08;只需要安装一次&#xff09; npm i -g nestjs/cli 进入要创建项目的目录&#xff0c;使用 Nest CLI 创建项目 nest new 项目名 运行项目 npm run start 开发环境下运行&#xff0c;自动刷新服务 npm run start:dev 2、…...

DDL:针对于数据库、数据表、数据字段的操作

数据库的操作 # 查询所有数据 SHOW DATABASE; #创建数据库 CREATE DATABASE 2404javaee; #删除数据库 DROP DATABASE 2404javaee; 数据表的操作 #创建表 CREATE TABLE s_student( name VARCHAR(64), s_sex VARCHAR(32), age INT(3), salary FLOAT(8,2), c_course VARC…...

昇思学习打卡-5-基于Mindspore实现BERT对话情绪识别

本章节学习一个基本实践–基于Mindspore实现BERT对话情绪识别 自然语言处理任务的应用很广泛&#xff0c;如预训练语言模型例如问答、自然语言推理、命名实体识别与文本分类、搜索引擎优化、机器翻译、语音识别与合成、情感分析、聊天机器人与虚拟助手、文本摘要与生成、信息抽…...

Java中 普通for循环, 增强for循环( foreach) List中增删改查的注意事项

文章目录 俩种循环遍历增加删除1 根据index删除2 根据对象删除 修改 俩种循环 Java中 普通for循环&#xff0c; 增强for循环( foreach) 俩种List的遍历方式有何异同&#xff0c;性能差异&#xff1f; 普通for循环&#xff08;使用索引遍历&#xff09;&#xff1a; for (int…...

昇思25天学习打卡营第19天|LSTM+CRF序列标注

概述 序列标注指给定输入序列&#xff0c;给序列中每个Token进行标注标签的过程。序列标注问题通常用于从文本中进行信息抽取&#xff0c;包括分词(Word Segmentation)、词性标注(Position Tagging)、命名实体识别(Named Entity Recognition, NER)等。 条件随机场&#xff08…...

微服务: 初识 Spring Cloud

什么是微服务? 微服务就像把一个大公司拆成很多小部门&#xff0c;每个部门各自负责一块业务。这样一来&#xff0c;每个部门都可以独立工作&#xff0c;即使一个部门出了问题&#xff0c;也不会影响整个公司运作。 什么是Spring Cloud? Spring Cloud 是一套工具包&#x…...

探索InitializingBean:Spring框架中的隐藏宝藏

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》《MYSQL》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 ✨欢迎加入探索MYSQL索引数据结构之旅✨ &#x1f44b; Spring框架的浩瀚海洋中&#x…...

JVM专题之垃圾收集算法

标记清除算法 第一步:标记 (找出内存中需要回收的对象,并且把它们标记出来) 第二步:清除 (清除掉被标记需要回收的对象,释放出对应的内存空间) 缺点: 标记清除之后会产生大量不连续的内存碎片,空间碎片太多可能会导致以后在程序运行过程中需 要分配较大对象时,无法找到…...

2024年6月后2周重要的大语言模型论文总结:LLM进展、微调、推理和对齐

本文总结了2024年6月后两周发表的一些最重要的大语言模型论文。这些论文涵盖了塑造下一代语言模型的各种主题&#xff0c;从模型优化和缩放到推理、基准测试和增强性能。 LLM进展与基准 1、 BigCodeBench: Benchmarking Code Generation with Diverse Function Calls and Com…...

大数据面试题之数仓(1)

目录 介绍下数据仓库 数仓的基本原理 数仓架构 数据仓库分层(层级划分)&#xff0c;每层做什么?分层的好处? 数据分层是根据什么? 数仓分层的原则与思路 知道数仓建模常用模型吗?区别、优缺点? 星型模型和雪花模型的区别?应用场景?优劣对比 数仓建模有哪些方式…...

[机器学习]-4 Transformer介绍和ChatGPT本质

Transformer Transformer是由Vaswani等人在2017年提出的一种深度学习模型架构&#xff0c;最初用于自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;特别是机器翻译。Transformer通过自注意机制和完全基于注意力的架构&#xff0c;核心思想是通过注意力来捕捉输入序列…...

基于深度学习的电力分配

基于深度学习的电力分配是一项利用深度学习算法优化电力系统中的电力资源分配、负荷预测、故障检测和系统管理的技术。该技术旨在提高电力系统的运行效率、稳定性和可靠性。以下是关于这一领域的系统介绍&#xff1a; 1. 任务和目标 电力分配的主要任务是优化电力系统中的电力…...

飞书 API 2-4:如何使用 API 将数据写入数据表

一、引入 上一篇创建好数据表之后&#xff0c;接下来就是写入数据和对数据的处理。 本文主要探讨数据的插入、更新和删除操作。所有的操作都是基于上一篇&#xff08;飞书 API 2-4&#xff09;创建的数据表进行操作。上面最终的数据表只有 2 个字段&#xff1a;序号和邮箱。序…...

系统设计题-日活月活统计

一、题目描述 根据访问日志统计接口的日活和月活。日志格式为 yyyy-mm-dd|clientIP|url|result 其中yyyy-mm-dd代表年月日&#xff0c;一个日志文件中时间跨度保证都在同一个月内&#xff0c;但不保证每行是按照日期顺序。 clientIP为合法的点分十进制ipv4地址(1.1.1.1和1.01.…...

在CentOS7云服务器下搭建MySQL网络服务详细教程

目录 0.说明 1.卸载不要的环境 1.1查看当前环境存在的服务mysql或者mariadb 1.2卸载不要的环境 1.2.1先关闭相关的服务 1.2.2查询曾经下载的安装包 1.2.3卸载安装包 1.2.4检查是否卸载干净 2.配置MySQLyum源 2.1获取mysql关外yum源 2.2 查看当前系统结合系统配置yum…...

【数据结构与算法】快速排序霍尔版

&#x1f493; 博客主页&#xff1a;倔强的石头的CSDN主页 &#x1f4dd;Gitee主页&#xff1a;倔强的石头的gitee主页 ⏩ 文章专栏&#xff1a;《数据结构与算法》 期待您的关注 ​...

无人机5公里WiFi低延迟图传模组,抗干扰、长距离、低延迟,飞睿智能无线通信新标杆

在科技日新月异的今天&#xff0c;我们见证了无数通信技术的飞跃。从开始的电报、电话&#xff0c;到如今的4G、5G网络&#xff0c;再到WiFi的广泛应用&#xff0c;每一次技术的革新都极大地改变了人们的生活方式。飞睿智能5公里WiFi低延迟图传模组&#xff0c;它以其独特的优势…...

Kappa架构

1.Kappa架构介绍 Kappa架构由Jay Kreps提出&#xff0c;不同于Lambda同时计算和批计算并合并视图&#xff0c;Kappa只会通过流计算一条的数据链路计算并产生视图。Kappa同样采用了重新处理事件的原则&#xff0c;对于历史数据分析类的需求&#xff0c;Kappa要求数据的长期存储能…...