我正在进行一个Go项目,在那里我使用一些相当大的第三方客户端库来与一些第三方REST apis进行通信。我的目的是将我的内部代码API与这些特定的依赖项分离开来。
将特定方法与代码中的这些库分离是很简单的,因为我只需要功能的一个子集,并且能够抽象用例。因此,我在代码中引入了一种新类型,它实现了我的特定用例;底层实现则依赖于第三方依赖项。
我有一个问题要了解如何找到一个好的解耦是configuration structs。通常,我使用的客户端库提供此表单的一些功能。
createResourceA(options *ResourceAOptions) (*ResourceA, error)
createResourceB(options *ResourceBOptions) (*ResourceB, error)其中*ResourceA和*ResourceB是创建后相应资源的服务器端配置。
不同的options是具有大量字段、嵌套结构等资源的相当大的配置结构。一般来说,这些配置包含了我的应用程序所需的更多选项,但最终总的重叠程度相当大。
由于我希望避免内部代码必须导入特定的依赖项才能访问配置结构,所以我希望封装这些依赖项。
我目前的封装方法是定义自己的配置结构,然后使用这些结构配置第三方依赖项。举一个简单的例子:
import a "github.com/client-a"
// MyClient implements my use case functions
type MyClient struct{}
// MyConfiguration wraps more or less the configuration options
// provided by the client-a dependency
type MyConfiguration struct{
Strategy StrategyType
StrategyAOptions *StrategyAOptions
StrategyBOptions *StrategyBOptions
}
type StrategyType int
const (
StrategyA StrategyType = iota
StrategyB
)
type StrategyAOptions struct{}
type StrategyBOptions struct{}
func (c *MyClient) UseCaseA(options *MyConfiguration) error {
cfg := &a.Config{}
if (options.Strategy = StrategyA) {
cfg.TypeStrategy = a.TypeStrategyXY
}
...
a.CreateResourceA(cfg)
}如示例所示,使用这种方法,我可以封装第三方配置结构,但我认为这个解决方案的扩展性不太好。我已经遇到了一些例子,在这些例子中,我基本上是从代码中的依赖项中重新实现类型,只是为了抽象出依赖关系。
在这里,我正在寻找更复杂的解决方案和/或一些洞察力,如果我的方法通常是错误的。
进一步研究来自我:
我查看了struct embedding,如果这对我有帮助的话。但是,由于配置包含非平凡的成员,我最终也会在调用代码中导入依赖项来填充字段。
由于通常的指导方针似乎是Accept interfaces return structs,所以我试图用这种方法找到一个很好的解决方案。但是在这里,我也可以得到一个相当大的接口,在go标准库中,配置结构似乎不能通过接口使用。如果在Go中将配置隐藏在接口后面是一种很好的做法,我无法找到一个显式的语句。
来总结它:
我想知道如何从第三方库中抽象配置结构,而不会在代码中重新定义相同的数据类型。
发布于 2019-07-25 14:27:34
那么一件非常简单的事情呢--重新定义包装包中所需的结构类型?
我是新来的,所以这可能不是最好的办法。
package myConfig
import a "github.com/client-a"
type aConfig a.Config那么您只需要导入您的myConfig包
import "myConfig"
// myConfig.aConfig is actually a.Config
myConfig.aConfig不太确定这是否有很大帮助,因为这不是真正的解耦,但至少您不需要在每个地方导入"github.com/client-a“。
https://stackoverflow.com/questions/57203802
复制相似问题