【问题标题】:Multiple interfaces for the same struct同一个结构的多个接口
【发布时间】:2019-09-01 18:59:29
【问题描述】:

我正在学习 Go,并且想知道在某些情况下,是否认为在 Golang 中为同一 struct 创建多个 interface 变体是否被认为是好的/好的/典型的(鼓励的?)变体,具体取决于消费者代码将是什么用那个结构做什么?

我对此提出质疑,因为我有一个结构对象,可以说它在我的代码库中做的太多了,我想添加一些测试并仅模拟该结构的某些用法/消费者。说我有,

对于(人为的)示例,环境结构

// Environment/env.go

package env

type Environment struct {
  sunny bool,
  fullMoon bool,
  temp float64
  // ...
}

func (e *Environment) IsSunny() bool {
  return e.sunny
}

func (e *Environment) IsFullMoon() bool {
  return e.fullMoon
}

func (e *Environment) GetTemp() float64 {
  return e.temp
}

上述结构具有与一些环境条件(白天和夜间)相关的属性和方法。

那么这个结构有多个消费者,但每个interface只关心可用方法的一个子集:

// daytime.go

type DayEnv interface {
  IsSunny() bool
  GetTemp() float64
}

func getDaytime(de DayEnv) {
  sunStatus := getSunStatus(de)
  temp      := getDayTemp(de)

  fmt.Printf("Today is %s and temperature is %s", sunStatus, temp)
}

// func getSunStatus(de DayEnv) string {}
// func getDayTemp(de DayEnv) string {}
// nightTime.go

type NightEnv interface {
  IsFullMoon() bool
  GetTemp() float64
}


func getNighttime(ne NightEnv) {
  moonPhase := getMoonPhase(ne)
  temp      := getNightTemp(ne)

  fmt.Printf("Tonight the moon is %s and temperature is %s", moonPhase, temp)
}

// func getMoonPhase(ne NightEnv) string { }
// func getNightTemp(ne NightEnv) string { }

在我看来,虽然创建一个只关注结构方法子集的新接口会使事情变得更加灵活,但拥有如此多(部分)重复的接口并将它们洒在需要或在哪里消费。我意识到这个例子有点做作,但是在更大的范围内(比如很多很多消费者),或者一个文件可能有相同结构的x 接口......这种方法有什么问题吗?

【问题讨论】:

  • 在我看来,您的代码显示了 “Duck typing” 是什么,我认为这是 Go 的核心概念之一。

标签: oop go struct


【解决方案1】:

这种方法没有错,Go 标准库经常使用它。例如,有许多结构体实现了 io.Reader、io.Writer、io.Closer 和 io.Seeker 的组合。这些结构的用户指定他们需要什么类型的接口并使用它。

【讨论】:

  • 除此之外,拥有 1-2 个小的方法接口可以提高程序的可读性,因为它可以更明确地说明某些函数的期望。编写 mock 也变得容易得多,因为您不需要为只希望使用接口中的一种方法的函数模拟整个接口。
  • 此外,使用小型界面的做法使其在以后的工作中变得容易。如果您有一个未来可能会增长的单一接口,那么您最好现在就花时间将其拆分,而不是等到使用起来很麻烦,然后再进行重构。
【解决方案2】:

接口是golang实现“多态”必不可少的部分。不仅做对了,还找到了界面的精髓。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多