go - 如何解耦这种传递依赖

标签 go decoupling

我试图弄清楚如何从我的服务中删除传递依赖。
让我们调用我的服务服务A .
服务A 取决于 图书馆 B . 图书馆 B 取决于 图书馆C .为此服务A 传递地取决于 图书馆C .让我解释一下如何...
在这种情况下 图书馆C 恰好是 ozzo 验证 图书馆。在这个库中有一个名为 Errors 的类型。定义为 map[string]error .您可以在 https://github.com/go-ozzo/ozzo-validation/blob/v3.6.0/error.go 上查看但这里仅供引用:

package validation

type Errors map[string]error

// Implement the error interface
func (es Errors) Error() string {
    // Implementation omitted for brevity
}
注意类型 Errors实现 error界面。
正如我已经写过的 图书馆 B 取决于 图书馆C , ozzo- 验证 . 图书馆 B 的使用ozzo 验证 这是:
package web

// Error responds to a request with an error object and the specified status
func Error(w http.ResponseWriter, err error, status int) {
    // Implementation omitted for brevity
    errors, ok := err.(validation.Errors)
    if ok {
        for key, err1 := range errors {
            // Implementation omitted for brevity
        }
        // Implementation omitted for brevity
    }
    // Implementation omitted for brevity
}
这就是整个用法。 图书馆 B 进口 ozzo 验证 这样图书馆 B 可以做类型断言,errors, ok := err.(validation.Errors) ,然后在 map 上进行范围,for key, err1 := range errors .
我的服务,服务A , 不知道 图书馆 B 依赖于 ozzo 验证 . 服务A 也想用 ozzo 验证 ,但需要使用较新的版本,因为较新的版本具有更多功能和一些重要的错误修复。这个较新的版本是 v4.3.0。 服务A 调用 中的一些方法ozzo 图书馆 返回 validation.Errors实例并将该实例传递给 图书馆 B web.Error用作err error范围。
这就是乐趣的开始。因为服务A 正在传入 v4.3.0 validation.Errors实例和 图书馆 B 是针对 v3.6.0 validation.Errors 的类型断言即使 v3.6.0 和 v4.3.0 中的类型定义完全相同,类型断言也会失败。
我该如何解决这个问题?
我确实可以访问 图书馆 B 的源代码,我可以更改它。我可以轻松升级图书馆 B 使用 的 v4.3.0 ozzo 验证 ,但这会使这种传递耦合永久化。我宁愿完全移除这种传递耦合。
我尝试更改 中的类型断言图书馆 B
errors, ok := err.(map[string]error)
因为最终这正是实例的样子,map[string]error但是编译器不喜欢这样,因为 map[string]error没有实现 error界面。
有什么方法可以让我自己的对象实现 error并且还可以范围,以便我可以将 v4.3.0 `validation.Errors 包装在某种接口(interface)中,或者会破坏这种传递耦合的东西?
我能做些什么来打破这种紧密的传递耦合?

最佳答案

如果需要考虑 LibraryB 的向后兼容性,则不能仅将 LibraryB 中的 ozzo-validation 升级到 v4。因为如果有一个使用 LibraryC@v3 和 LibraryB 的 ServiceD,这样的升级会破坏 ServiceD。
幸运的是,在 Go Modules 的帮助下,LibraryB 可以导入 v3 和 v4 并对这两个版本进行类型断言。

package web

import (
 validationv3 "github.com/go-ozzo/ozzo-validation/v3"
 validationv4 "github.com/go-ozzo/ozzo-validation/v4"
)

// Error responds to a request with an error object and the specified status
func Error(w http.ResponseWriter, err error, status int) {
    // Implementation omitted for brevity
    errorsv3, ok := err.(validationv3.Errors)
    if ok {
        for key, err1 := range errorsv3 {
            // Implementation omitted for brevity
        }
        // Implementation omitted for brevity
    }
    // Implementation omitted for brevity


    errorsv4, ok := err.(validationv4.Errors)
    if ok {
        for key, err1 := range errorsv4 {
            // Implementation omitted for brevity
        }
        // Implementation omitted for brevity
    }
    // Implementation omitted for brevity

}

关于go - 如何解耦这种传递依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66166559/

相关文章:

validation - URL 验证似乎已损坏

mongodb - 无法创建/访问数据库

mysql - 使用 golang 将数组中的行批量插入到 SQL Server

java - 使用队列解耦程序

c# - 与 ConfigurationManager 耦合或将参数从一个传递到另一个

java - 这是什么设计模式?打印PersonsOlderThan

c - 如何设计一个程序,使 GUI 和程序逻辑分离

go - 如何在 Go 中使用 JWK 验证 JWT 签名?

memory - 如果字段顺序不同,则结构具有不同的大小

microservices - 微服务应该是可重用的吗?