go - 部分实现接口(interface)的最佳实践

标签 go

部分提供默认实现的方法是什么?

为了说明,以下切换开关驱动程序的简单示例是我遵循我的 OO 直觉而结束的死胡同......当然它不会编译(我知道为什么)而且我不一定愿意这样做所以。 任何其他解决方案更好地适应 go 哲学实际上会更好地正确理解这种常见需求的 go-way。


完整的示例也可以在 https://play.golang.org/p/MYED1PB-dS 找到

给定以下界面:

type ToggleSwitch interface {
    TurnOn()
    TurnOff()
    IsOn() bool
    Toggle()
}

Toggle() 是提供默认实现(即根据当前状态打开或关闭开关)的一个很好的候选者:

// The Toggle() method can already be defined using TurnOn, TurnOff() and IsOn().
type DefaultDriver struct {
}

// The following implementation would be fine for non-optimized cases:
func (d *DefaultDriver) Toggle() {
    state := d.IsOn()
    fmt.Println("generic toogle ->", state)
    if state {
        d.TurnOff()
    } else {
        d.TurnOn()
    }
}

然后实际的驱动程序可以使用或不使用它:

// Example of an actual ToggleDriver which should fully implement the interface
// based on the default implementation or not.
// For example, if the toggle switch device has a bult-in toggle command, the
// Toggle() method could be optimized to directly use it.
type DummyDriver struct {
    *DefaultDriver // promote DefaultDriver methods
    state bool
}

func (d *DummyDriver) IsOn() bool {
    return d.state
}

func (d *DummyDriver) TurnOff() {
    d.state = false
}

func (d *DummyDriver) TurnOn() {
    d.state = false
}

// Uncomment me to optimize me...
//func (d *DummyDriver) Toggle() {
//  fmt.Println("specialized toogle ->", d.state)
//  d.state = !d.state
//}

最佳答案

就我个人而言,我会为 DefaultDriver 类型实现 Toggle、IsOn、TurnOn 和 TurnOff 方法,因此它会满足 ToggleSwitch 接口(interface)。

然后,DummyDriver 类型将嵌入 DefaultDriver 类型。

这样,您就可以根据需要为 DummyDriver 类型实现专门的方法。

结果会是这样的:

package main

import "fmt"

type ToggleSwitch interface {
    TurnOn()
    TurnOff()
    IsOn() bool
    Toggle()
}

type DefaultDriver struct {
    state bool
}

func (d *DefaultDriver) Toggle() {
    state := d.IsOn()
    fmt.Println("generic toogle ->", state)
    if state {
        d.TurnOff()
    } else {
        d.TurnOn()
    }
}

func (d *DefaultDriver) IsOn() bool {
    return d.state
}

func (d *DefaultDriver) TurnOff() {
    d.state = false
}

func (d *DefaultDriver) TurnOn() {
    d.state = true
}

type DummyDriver struct {
    DefaultDriver
    state bool
}

// Uncomment me to optimize me...
//func (d *DummyDriver) Toggle() {
//  fmt.Println("specialized toogle ->", d.state)
//  d.state = !d.state
//}

func main() {
    d := DummyDriver{state: false}
    d.Toggle()
    d.Toggle()
    d.Toggle()
}

https://play.golang.org/p/Xm-8A0xoRb

关于go - 部分实现接口(interface)的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35746895/

相关文章:

arrays - 为什么不能超过 *[]Struct?

google-app-engine - 如何使用 go 1.11 和 Google App Engine Standard 验证私有(private) Go 模块

go - 处理多语言 Go Web 应用程序的标准/惯用方法是什么?

go - golang程序退出后如何保持子进程运行?

post - Golang 和 Telegram API 的 400 错误请求

go - 将 if 语句转换为短语句

go - 为什么 filepath.Walk() panic ?

go - Stringers 接口(interface)是否仅适用于 golang 中的值接收器

go - 奇怪的错误消息: mismatched types rune and string

concurrency - 在 goroutine 中选择评估所有其他语句