golang抽取接口,依赖注入(依赖倒置)解决包引用关系

golang fx 依赖注入包学习笔记 这篇文章介绍一下go.uber.org/fx 包的使用,也是自己的学习笔记 下面代码是分析官方示例程序写的,包地址见godoc package main import ( "context" "fmt" "log" "net/http" "os" "time" "go.uber.org/fx" ) // 这里把main函数放到最前面,可以清晰的先了解代码调用方法,具体函数定义,... 阅读详情

本文首发于我的个人博客
本文记录了作者在golang开发中,通过抽取接口,依赖注入的方式,解决包与包之间的不合理引用关系。

总结来说:

面向接口编程,并且golang中接口函数的参数最好是标准库的类型

场景

目前项目中有一个业务逻辑包business_logic,两个工具库包pkg1和pkg2,其中

  • pkg1是旧库,API不宜改动,pkg2是新库,尚未正式使用
  • business_logic会使用pkg1和pkg2
  • pkg1内部要添加使用pkg2的逻辑
// pkg1/main.go
package pkg1

import "pkg2"

func ExternalAPI() {
    pkg2.ExternalAPI(pkg2.S{})
}

// pkg2/main.go
package pkg2

type S struct {
    param1 int
}

func ExternalAPI(s S) {
}
// business_logic/main.go
package main

import (
    "pkg1"
    "pkg2"
)

func main() {
    pkg1.ExternalAPI()
    pkg2.ExternalAPI(pkg2.S{})
}

这样就引起了一个问题:

business_logic其实引用了两次pkg2,一次是直接引用,一次是通过pkg1间接引用,将来在版本更迭中,很有可能会出现直接引用的版本和间接引用的版本不一致的情况,从而引起未知bug

解决尝试

如果不希望两次引用,那么最好的方式是消除pkg1对pkg2的引用,消除引用的方式是

  • pkg1抽象出一个接口,
  • 让pkg2提供结构体,实现pkg1抽象出的接口

这样,pkg2实际上就变成了pkg1的一个插件,只要在business_logic初始化的时候,将pkg2的插件注入到pkg1里去就行

但是这样的尝试失败了,我们先来看一下代码

// pkg1/main.go
package pkg1

import "pkg2"

type Plugin interface {
    ExternalAPI(s pkg2.S)
}

var plugin Plugin

func ExternalAPI() {
    if plugin != nil {
        plugin.ExternalAPI(pkg2.S{})
    }
}

func SetPlugin(p Plugin) {
    plugin = p
}
// pkg2/main.go
package pkg2

type S struct {
    param1 int
}

type Plugin struct {
}

func (p *Plugin) ExternalAPI(s S) {
}

func ExternalAPI(s S) {
    p := Plugin{}
    p.ExternalAPI(s)
}
// business_logic/main.go
package main

import (
    "pkg1"
    "pkg2"
)

func main() {
    pkg1.SetPlugin(&pkg2.Plugin{})
    pkg1.ExternalAPI()
    pkg2.ExternalAPI(pkg2.S{})
}

我们发现,pkg1对pkg2的引用仍旧存在,其原因在于抽取出来的接口函数中的参数是属于pkg2的

type Plugin interface {
    ExternalAPI(s pkg2.S)
}

最终解决方案

由于pkg2是新库,所以我们决定更改它的接口,最终的代码如下

// pkg1/main.go
package pkg1

type Plugin interface {
    ExternalAPI(param int)
}

var plugin Plugin

func ExternalAPI() {
    if plugin != nil {
        plugin.ExternalAPI(0)
    }
}

func SetPlugin(p Plugin) {
    plugin = p
}
// pkg2/main.go
package pkg2

type Plugin struct {
}

func (p *Plugin) ExternalAPI(s int) {
}

func ExternalAPI(s int) {
    p := Plugin{}
    p.ExternalAPI(s)
}
// business_logic/main.go
package main

import (
    "pkg1"
    "pkg2"
)

func main() {
    pkg1.SetPlugin(&pkg2.Plugin{})
    pkg1.ExternalAPI()
    pkg2.ExternalAPI(0)
}

可以看到,这回彻底解决了pkg1引用pkg2的问题,代价就是将pkg2.S这个结构体参数展开了

视具体业务情况而定,我们可以通过:

  1. 展开结构体
  2. 将结构体换做map[string]interface{}(当然需要手动做字段的提取和塞入)
  3. 将结构体换做string,用JSON传参(手动Marshal和Unmarshal)
  4. 将参数类型放到新的第三方库pkg3中(这样就又要维护引用的pkg3版本一致)

软件开发中没有silver-bullet,只有trade-off,这次的方案,也还算满意

从零开始学习 Go 1.25 编程 今天是你新生活的第一天,无论年龄、背景如何,改变从这一刻开始。CodeGym帮助成千上万普通人转型为程序员,从零基础到掌握Go语言,完成真实项目,甚至入职心仪岗位。Go语言简洁高效,适合服务器端开发,是云基础设施、微服务和高负载系统的首选。2026年正是入行良机,你的经验反而是优势。别犹豫,迈出第一步,你将收获技能、自信与全新人生。🚀 阅读详情

相关推荐

golang不到30行代码实现依赖注入的方法

主要介绍了golang不到30行代码实现依赖注入的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

用依赖倒置和控制反转,突破Golang循环调用限制之后的思考

通过很简单的代码依赖注入和控制反转的方法,就可以为代码带来很大的灵活性,使代码结构变得更加有弹性

liuwill的博客 1961

用化学方法nmp溶剂从佳能cmos传感器上剥离拜耳矩阵和微透镜

将光刻胶暴露于 NMP 溶剂中 10-15 分钟,并进行轻微的机械搅拌,将溶解的光刻胶从基材表面带走,即可去除大部分光刻胶,之后再进行第二次溶剂浴,以洗去微量含有光刻胶的溶剂。我还担心传感器的校准问题,我觉得可以大致解决这个问题,比如在安装面上用刻度尺标记三个螺丝的位置,然后数着拧出螺丝的圈数,直到听到“咔哒”声(螺纹完全拧出)。我还担心传感器的校准问题,我觉得可以大致解决这个问题,比如在安装面上用刻度尺标记三个螺丝的位置,然后数着拧出螺丝的圈数,直到听到“咔哒”声(螺纹完全拧出)。在我看来,这是必读的;

qq_40247880的博客 1476

【go】依赖倒置demo

为降低代码耦合性,采用依赖注入的设计模式。原始请求路径:router -> api -> service -> dao。请求的为实际方法,具有层层依赖的关系。现将方法抽象为接口,即a依赖b,但a不创建(或销毁)b,仅使用b,b的创建(或销毁)交给容器。

微雨停了的博客 1065

ubuntu通过qemu安装银河麒麟V10_Arm_v8 (kylin_v10_飞腾/鲲鹏版)

一、windows下安装vmware虚拟机 二、ubuntu下载地址 https://mirrors.tuna.tsinghua.edu.cn/ubuntu-releases/20.04/ubuntu-20.04.3-live-server-amd64.iso 三、vmware中新建虚拟机,并使用ubuntu-20.04.3-live-server-amd64.iso作为启用盘 。。。在虚拟机中安装ubuntu(略) 四、配置ssh(如果ssh登录不上时配置) 修改openssh的配置 vi /etc/s

u010533742的博客 8704

【架构设计】DDD 到底解决了什么问题

DDD作为架构设计思想帮助微服务控制规模复杂度,那它是怎么做到的呢?第一章提出了架构的根本目是解决系统复杂度,并简要说明系统复杂度的六个来源及通用解法,为我们设计架构提供了清晰可执行的操作思路。

DreamSun的博客 1161

go实现依赖倒置(简易版)

依赖倒置是一种通用的软件设计原则,不要让高层依赖底层,而要让底层依赖高层的抽象。这个是我根据别人的博客里面的概念理解实现的,如有谬误欢迎指出。

江南孟浪生的博客 417

手把手带你实现DAF-Net:零代码基础入门红外与可见光图像融合(从理论到实战)

本文介绍了红外与可见光图像融合技术及DAF-Net网络的应用。红外图像能捕捉热源但缺乏细节,可见光图像纹理丰富但在低光环境下表现不佳。DAF-Net采用双分支特征提取和动态注意力融合架构,能智能分配特征权重实现优势互补。文章详细讲解了环境配置、数据集准备(如TNO数据集)和预处理方法,并提供了DAF-Net的核心代码实现,包括特征提取、注意力融合和图像重建模块。通过该技术可在安防、自动驾驶等领域获得更优质的融合图像,提升视觉感知能力。

m0_71589036的博客 229

golang 设计模式(创建型模式, 结构型模式,行为型模式)

七大原则 开闭原则 依赖倒置原则(依赖反转原则) 单一职责原则 接口隔离原则 迪米特法则 里氏代换原则 合成复用原则 创建型模式 简单工厂模式 工厂模式 抽象工厂模式 结构型模式 适配器模式 装饰者模式&装饰器 外观模式 组合模式 享元模式 桥接模式 代理模式 行为型模式 责任链模式 命令模式 观察者模式 解释器模式 状态模式 策略模式 模板模式 迭代器模式 中介者模式 备忘录模式

hunyxv的博客 841

用 ABAP OAuth 2.0 Client 直连 SAP SuccessFactors:从体系到落地的一条龙实践指南

ABAP SMI允许在后端对外部服务的OData端点进行定义与自定义化配置,并以受信连接的方式暴露给ABAP应用调用。它并不替代OAuth,而是扮演端点与自定义参数的集中化定义者,最终认证依旧由完成。对于需要在ABAP后端发起临时或补充型OData调用的场景,SMI是一个轻量而清晰的集成入口。scope的客户端应用已经完成注册,API DomainCompany ID、证书或密钥都已归档。ABAP的Profile与Client已建立并绑定,OA2C_GRANT可见绿色访问状态。SMI。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 286

RK3568平台(KBuild篇)KBuild编译体系

从Linux内核2.6开始,Linux内核的编译采用Kbuild系统,这和过去的编译系统有很大的不同,尤其对于Linux内核模块的编译。在新的系统下,Linux编译系统会两次扫描Linux的Makefile:首先编译系统会读取Linux内核顶层的Makefile,然后根据读到的内容第二次读取Kbuild的Makefile来编译Linux内核。kbuild,即 kernel build,用于编译 Linux 内核文件。

weixin_49303682的博客 349

Go实战抢红包系统(三)-架构设计

项目的代码架构设计就是作战线路规划。本文从Why、What、How三个维度来介绍代码架构,说明代码架构意义、要做的事、常见的代码分层。从四层架构来阐述每一层职责,最后介绍Go module模块化管理代码工具。… 1 代码架构的意义 代码架构就是详细设计中的核心内容! 1.1 代码架构承上启下,决定软件质量 ◆ 承上 说明业务逻辑和业务领域模型 ◆ 本身 保证代码有更好的可读性和可维护性、可扩展性...

JavaEdge全是干货的技术号 2583

ncode控件使用总结

数据格式txt转s3t #HEADER #TITLES Absolute_Time,COG_Ax,COG_Ay,COG_Az,LF_SPINDLE_AZ #UNITS ,g,g,g,g, #DATATYPES Double,Float,Float,Float,Float #DATA 2. 导入s3t数据 3. 输入数据控件 直接拖入数据源或者添加控件数据 4.

技术联盟 2006

一套可供参考的Go微服务开发方法论

▲点击上方“分布式实验室”关注公众号回复“1”抽取纸质技术书本文从简洁架构的理论出发,依托trpc-go目录规范,简单阐述了整体代码架构如何划分,具体trpc-go服务代码实现细节,和落地步骤,并讨论了和DDD的区别。文章源于作者组内发起的Go微服务最佳实践的第一部分,希望从开发和阅读学习中总结出一套Go微服务开发的方法论,互相分享一下在寻求最佳的实践过程中的思考和取舍...

Docker的专栏 802

【Burp入门第二十二篇】BurpSuite配置Hea插件教程+添加配置项

HaE是一个基于BurpSuite Java插件API开发的辅助型框架式插件,旨在实现对HTTP消息的高亮标记和信息提取。该插件通过自定义正则表达式匹配响应报文或请求报文,并对匹配成功的报文进行标记和提取。

等风来 9627

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

从代码坏味道到清晰架构:Java项目重构实战与最佳实践

代码重构是提升软件可维护性与团队协作效率的核心工程实践,其本质是在不改变外部行为的前提下,通过系统性的结构调整优化代码内部设计。重构遵循小步快跑、安全第一的原则,通常从识别代码坏味道(如过长函数、重复代码、过大类)入手,运用提取方法、提炼类等手法进行改进。在架构层面,通过分层设计、领域驱动设计(DDD)轻量应用和依赖注入(DI)等技术,可以有效实现高内聚、低耦合的目标,从而提升代码的可测试性和扩展性。本文以Java Spring Boot项目为例,通过一个典型的订单服务重构案例,详细演示了如何将臃肿的“上帝

weixin_33994429的博客 346

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Golang设计模式

Golang设计模式 Golang设计模式 一.面向对象设计原则 ​ 1.1 单一职责原则 类的职责单一,对外只提供一种功能,而引起类变化的原因都应该只有一个。 //不遵守单一职责原则 package main import "fmt" /* 在这个例子中,Clothes 类包含了两个方法 onWork() 和 onShop(),这两个方法描述了在不同场景下(工作和购物)穿着相同的装扮。 问题在于这两种场景虽然使用了相同的装扮, 但它们实际上是两种不同的行为或上下文。 */ type Clothes

猫狗鼠鱼的储物间 1147

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Go 接口设计:小接口、组合与依赖倒置

这是 Go 和 Java 最大的思维差异。Java 习惯先定义接口再写实现,接口和实现放一起。Go 推荐在使用接口的那个包里定义接口,实现方甚至不需要知道接口的存在——因为 Go 是隐式实现(鸭子类型),只要方法签名对得上就自动满足接口。// package report —— 消费方,在这里定义它需要什么// package user —— 实现方,压根没 import report,也没写 implements// 只要签名匹配,Service 自动满足 report.UserGetter。

weixin_42662753的博客 483

架构设计(二)倒置依赖的正确打开方式

依赖倒置原则(DIP)是面向对象设计的核心原则之一,强调高层模块和低层模块都应依赖于抽象,而非直接相互依赖。该原则通过解耦、提高扩展性和可测试性,使系统更灵活。实现方式包括面向接口编程、依赖注入和工厂模式。在架构层面,DIP适用于分层架构、微服务和事件驱动架构。实践中需避免过度抽象或接口设计不合理,应结合业务需求识别变化点。依赖注入技术(手动或IoC容器)是实现DIP的关键,主流框架如Spring、.NET Core等均支持。

onlymscn的博客 1479

什么是Golang中的包循环问题?如何规避?

Go语言的设计原则之一是简洁性和可读性。禁止包循环是为了简化编译器的工作,提高代码的可维护性。在实际开发中,避免包循环的方法包括使用接口、依赖倒置原则和良好的规划。通过实际开发案例,我们演示了如何避免包循环,通过引入接口和依赖倒置原则,构建清晰而有序的包依赖关系。好的规划和设计有助于提高代码的可维护性和可扩展性,使得系统更加健壮和易于理解。希望本文对大家在Golang项目中避免包循环和进行好的规划提供了实用的帮助!

weixin_53623989的博客 1263

golang中关于依赖注入的几种使用方式(概念与代码示例)

本文介绍了Go语言中依赖注入(DI)的四种实现方式。构造函数注入是最推荐的方式,强制明确依赖关系;接口注入通过方法注入依赖;属性注入直接赋值依赖字段;DI容器框架如Google Wire可自动生成依赖代码。文章通过代码示例详细说明每种方式的用法,并对比了它们的优缺点。最后解答了两个常见问题:指针传递与值传递的区别,以及Wire框架对接口绑定的支持情况。依赖注入有助于解耦代码、提高可测试性和可维护性,在Go项目中可根据需求选择合适的方式实现。

bojinyuan00的博客 1463

依赖反转 依赖注入_在go中使用依赖反转

依赖反转 依赖注入 什么是依赖倒置? (What is Dependency Inversion?) Dependency Inversion is the idea that high-level logic should not depend on its low-level implementations. Business logic in our application should n...

weixin_26714375的博客 346

golang 依赖控制反转(IoC)

  主流开发语言,为了达到项目间的低耦合,都会借助IoC框架来实现。即抽象和实现分离,使用抽象层,不用关心这些抽象层的具体实现;抽象层的实现,可以独立实现。现在比较流行的领域驱动设计(ddd),为了达到将领域层作为最核心,也需要依赖于IOC。   回过头来,我们看看golang实现的ioc框架,有golang风格的框架,也有从其他主流语言搬过来的比较重的框架。我觉得目前实现最轻量级的,当属mar...

weixin_30764883的博客 494

php 依赖倒置原则,手撸golang 架构设计原则 依赖倒置原则

golang 架构设计原则 依赖倒置原则缘起最近复习设计模式拜读谭勇德的<>该书以java语言演绎了常见设计模式本系列笔记拟采用golang练习之依赖倒置原则依赖倒置原则(Dependence Inversion Principle, DIP)指设计代码结构时,高层模块不应该依赖底层模块,二者都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。常见的依赖注入方式有: 方法参数注入...

weixin_39560029的博客 201

依赖倒置原则(Dependence Inversion Principle)

一、 依赖倒置原则的定义依赖倒置原则(Dependence Inversion Principle,简称DIP) 依赖倒置原则的原始定义是: High level modules should not depend upon low level modules. Both should depend up on abstractions. Abstractions should not depe

qq_26847293的博客 782

Golang 设计模式

Golang实现设计模式的源码地址:     https://github.com/zhenbianshu/DesignPattern   策略模式(Strategy) 简介     策略模式:将算法或操作抽象成实现共同接口、可以被替换的类,实现逻辑和具体算法的解耦。     ·将各种行为抽象成算法,封装算法为对象;     ·算法实现共同接口,调用者调用时不考虑算法具体实现,调用接...

冷月醉雪的博客 847
上一篇: 编写自定义启动脚本时的注意项
下一篇: git-status中文乱码问题
fitzleopard
博客等级 码龄9年 6粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值