部分提供默认实施的方式是什么?
为了说明,以下简单的切换开关驱动程序示例是我通过遵循我的OO直觉结束的死胡同......当然它不编译(我知道为什么)而且我不一定愿意做所以。 任何其他解决方案更适合go go哲学实际上更好地正确理解这种共同需求的路径。
完整示例也可以在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
//}
答案 0 :(得分:3)
在我看来,你要做的事情并不像Go一样。
ToggleSwitch
定义了四种明确适用某种状态的方法。为了提供这些方法的任何的实现,您还需要实现该状态(即使该状态不存在,例如通过将这些方法定义为no-ops),但在那时,没有提供所有那些方法是没有意义的。
使用类似Go的类型组合,嵌入式类型通常应该是整个",完整且有用。嵌入式提供的方法仅适用于该领域,没有办法到达父母"或其方法。
如果ToggleSwitch
还有其他方法没有处理该状态,那么只提供接口的部分实现是有意义的,但在这一点上更好,更惯用的解决方案是将ToggleSwitch
定义为两个独立接口的组合。
换句话说,我不认为那里有一个" Go way"提供接口的部分实现(不是由几个接口组成),因为它在Go中用来定义尽可能小的接口。
答案 1 :(得分:2)
Personnally,我会为DefaultDriver类型实现Toggle,IsOn,TurnOn和TurnOff方法,因此它将满足ToggleSwitch接口。
然后,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()
}