微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何解耦这种传递依赖

如何解决如何解耦这种传递依赖

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

让我们将我的服务称为 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 包装在某种接口或会破坏它的东西中传递耦合?

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

解决方法

如果需要考虑 LibraryB 的向后兼容性,仅将 LibraryB 中的 ozzo-validation 升级到 v4 不是一种选择。因为如果有一个 ServiceD 使用 LibraryC@v3 和 LibraryB,这样的升级会破坏 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

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?