V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  chaleaochexist  ›  全部回复第 2 页 / 共 63 页
回复总数  1254
1  2  3  4  5  6  7  8  9  10 ... 63  
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@sthwrong 虽然你说的有瑕疵, 但是给我提供了新思路,我明天试一下. 谢谢佬友!!!
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 我没话讲了大佬, 后端 这么做不是太正常了吗?
一个 service 有多少个 io 操作啊 这都是最简单的了.
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@sthwrong 明白你的意思 你把 repo 放 provider 里了 就迎刃而解了. 这样就不需要 动态初始化了是吧.

逻辑上是的, 但是不符合业务逻辑吖...
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 啊? 我没跟上.. 啥意思?

我得意思是
```

type Repo struct {
db *sql.DB
}

func (r *Repo) GetUserByID(userID int) (*User, error) {
// ...
}

type UserService struct {
repo Repo
}

func NewService(repo Repo) *UserService {
return &UserService{repo: repo}
}

func (s *UserService) FindUserByID(userID int) (*User, error) {
user, err := s.repo.GetUserByID(userID)
if err != nil {
return nil, fmt.Errorf("service error: failed to find user with ID %d: %w", userID, err)
}
// 在这里可以添加业务逻辑
return user, nil
}

```

现在的要求是 1. 针对 FindUserByID 做单元测试. 2. 没有数据库 要求 mock 假数据.
你试试吧. 不算为难你吧.


我得问题是: 第一步 你需要实例化 NewService 你传什么参数进去? 你传一个真的, 那一定有一个真正的 db 连接, 传一个假的 编译失败.
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 你写个测试就知道了.
譬如 repo 访问数据库吧 现在需要你 在没有数据库的情况下测试 service 层的函数

如何 mock 假数据.
只有接口可以做到.

你传入一个结构体 结构体的依赖是 db.DB 他可是真的通过 TCP 去连数据库.

但是如果是接口 我就可以做一个假的 struct 去实现这个接口, 然后返回假数据就行了.

总之一句话 你尝试给你的 repo 层 写单元测试就明白了.
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 没办法模拟, 反正我不会...
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 你平时肯定不做单元测试. 我确定.
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 要么是我没说清楚, 要么是你没仔细看我得代码.

sshClient 是接口, 因为我现在的实现是 standardSshClient 将来可能基于第三方库去实现这个 sshclient. 所以 sshclient 需要定义成一个接口. 这是原因 1. 原因 2 如果 sshclient 是一个具体的结构体实现, 那么将来如何 mock? 如何做单元测试? 单元测试的时候, 需要脱机测试.

[意图显然是把 sshClient 作为一个实例而不是接口参数]
func Cmd1Handler(sshClient SSHClient) string {
的意图就是接口, 而不是实例.

原因是喜闻乐见的, Accept interfaces,return structs

至于为什么 CmdHandler 是一个函数而不是 sshclient 的方法. 是因为 除了我前面说的 sshclient 是一个接口还有一个原因是, 实际上情况比 demo 要复杂一点点除了 sshclient 还有 httpclient,
client 只负责执行, 而不考虑业务, CmdHandler 是带业务的, 就是我说的, 省略 100 行的内容.

==============================分隔
我得最后一个问题, 大佬帮忙看一下 v4 是否符合逻辑呢?
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 我猜 https://github.com/chaleaoch/golang_demo/tree/master/v4
这个文件夹下的代码 比较符合你的品味吧?

但是我得问题是, 如果我想注入 handler? 要如何做?
答案是不是: handler 就不应该注入 而是直接调用?

实际上我也是这么做的, 但是我需要你们 确认一下!!! 这回 我说明白了吗?
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 别着急大佬 等我再写一个版本 和你一起讨论.
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
实际上我第一版 --> 在我提供的 github 仓库中没有体现, 是我之前在工作中的第一版.
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 不过还是谢谢你耐心和我讨论问题... 希望你能和我继续 讨论.
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN

#3 的例子中 client.connect(ip) 的用法和 NewSshClient(ip) 没有本质区别.
实际上我第一版就是类似 client.connect(ip)的写法.

"sshClient 显然是个实例,咋会是接口呢。" 在我 github 的例子中 sshClient 是接口
https://github.com/chaleaoch/golang_demo/blob/master/v1/internal/task/a.go#L22

"都说了接口不是这么用."
接口实现了鸭子类型.
然后你说我得哪个接口用的不对是指 provider 吗? 通过 provider.GetFactory 拿到了一个 sshClient 的工厂函数, 然后再实例化这个 sshclient 是不对的, 应该直接传 sshclient 然后 sshclient.connect(ip) 是这个意思吗? 我没觉得这俩有本质区别啊.

但是我得例子中的问题不在这里, 而是引入了 handler 之后, 在哪里 定义接口的问题.
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 好吧...其实我根本就不会 java...
golang 如果不通过 interface 没法 mock.

或者 sshClient 这个接口 可以有多个实现. 我希望注入而不是将 NewsshClient1 改成 NewsshClient2
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
无论是 --> ~~无论是~~
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 像你这么写, 最大的问题是如何 mock?

无论是 GetByType 是查询数据库的, 如果不做成接口, 如何 mock
ssh 也是, 在单元测试的时候, 我不希望真的去 ssh 执行一条命令.
2025 年 8 月 13 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@everhythm
@darksword21
@Sendya
@iseki
@NessajCN
@sthwrong
@sunny352787
@Dorathea
@NessajCN

谢谢你们的回复, 我写了一个 伪代码, 希望可以把问题解释清楚.

https://github.com/chaleaoch/golang_demo.git

一共是三个版本 v1, v2, v3 我把问题都放到了注释中, 可以搜索关键字 "问题" . 各个版本之间的主要差别, 可以搜索关键字 "修改"

如果我得代码有其他的地方的写法上的问题, 随意批评指导, 谢谢你们. 谢谢!!
2025 年 8 月 12 日
回复了 chaleaochexist 创建的主题 Go 编程语言 请教 golang 依赖注入的实际问题
@NessajCN 因为注入嘛, 我在注入的时候(也就是初始化的时候) 是不知道 ip 的.

我现在的代码和你的例子差不多, 只不过不是用的 connect 而是注入了一个无参的函数, 这个函数返回一个工厂函数, 这个工厂函数返回 sshclient.

如果 sshclient 的 ip 是静态的类似 db.DB, 直接定义在 handler 和 task 的公共底层. 注入即可, 就没有这么多麻烦事了.
2025 年 8 月 10 日
回复了 chaleaochexist 创建的主题 程序员 grpc gateway 存在的意义是什么
@seth19960929 明白, 所以当后续有新的第三方需要 http 的场景的时候, 就是 grpc-gateway 大放光彩的时候了?

受教, 多谢.
2025 年 8 月 10 日
回复了 chaleaochexist 创建的主题 程序员 grpc gateway 存在的意义是什么
下载 --> 现在
json-web --> grpc-web
1  2  3  4  5  6  7  8  9  10 ... 63  
关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   2095 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 20ms · UTC 06:23 · PVG 14:23 · LAX 22:23 · JFK 01:23
♥ Do have faith in what you're doing.