Best practice to partially implement an interface
<p>What would be the go-way of <strong>partly</strong> providing a default implementation?</p>

<p>To illustrate, the following simple example of a toggle switch driver is the dead-end I ended with by following my OO intuition... Of course it does not compile (I know why) and I am not necessarily willing to do so. <strong>Any other solution</strong> better fitting into the go philosophy would be in fact even better to correctly understand the go-way for this common need.</p>

<hr>

<p>The complete example can also be found at <a href="https://play.golang.org/p/MYED1PB-dS" rel="noreferrer">https://play.golang.org/p/MYED1PB-dS</a></p>

<p>Given the following interface:</p>

<pre><code>type ToggleSwitch interface {
    TurnOn()
    TurnOff()
    IsOn() bool
    Toggle()
}
</code></pre>

<p><code>Toggle()</code> is a good candidate to be provided a default implementation (ie, according to the current state, turn on or off the switch):</p>

<pre><code>// 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 -&gt;", state)
    if state {
        d.TurnOff()
    } else {
        d.TurnOn()
    }
}
</code></pre>

<p>And then an actual driver could use it or not:</p>

<pre><code>// 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 -&gt;", d.state)
//  d.state = !d.state
//}
</code></pre>