如何解耦这种传递依赖

问题描述

我想弄清楚如何从我的服务中删除传递依赖。

让我们将我的服务称为 ServiceA

ServiceA 依赖于 LibraryBLibraryB 依赖于 LibraryC。因此,ServiceA 传递地依赖于 LibraryC。让我解释一下如何...

在这种情况下,LibraryC 恰好是 ozzo-validation 库。在这个库中,有一个名为 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 接口。

因为我已经写过 LibraryB 依赖于 LibraryC,ozzo-验证LibraryBozzo-validation 的使用是这样的:

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
}

这就是整个用法。 LibraryB 导入 ozzo-validation 以便 LibraryB 可以进行类型断言 errors,ok := err.(validation.Errors),然后在地图上进行范围 {{ 1}}。

我的服务 ServiceA 不知道 LibraryB 依赖于 ozzo-validationServiceA 也想使用 ozzo-validation,但需要使用更新的版本,因为新版本具有更多功能和一些重要的错误修复。这个较新的版本是 v4.3.0。 ServiceA 调用 ozzo-library 中的一些方法,这些方法返回一个 for key,err1 := range errors 实例并将该实例传递给 LibraryB 的 {{1} } 函数作为 validation.Errors 参数。

这就是乐趣的开始。由于 ServiceA 传入的是 v4.3.0 web.Error 实例并且 LibraryB 正在针对 v3.6.0 err error 进行类型断言,因此即使v3.6.0 和 v4.3.0 中的类型定义完全相同。

我该如何解决这个问题?

我确实可以访问 LibraryB 的源代码并且我可以更改它。我可以轻松地升级 LibraryB 以使用 ozzo-validation 的 v4.3.0,但这会使这种传递耦合永久化。我宁愿完全消除这种传递耦合。

我尝试将 LibraryB 中的类型断言更改为

validation.Errors

因为最终这正是实例的样子,validation.Errors 但编译器不喜欢那样,因为 errors,ok := err.(map[string]error) 没有实现 map[string]error 接口。

有什么方法可以让我自己的对象实现 map[string]error 并且也是范围可调的,这样我就可以将 v4.3.0 `validation.Errors 包装在某种接口或会破坏它的东西中传递耦合?

我该怎么做才能打破这种紧密的、可传递的耦合?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)