如何在Golang中保持代码DRY

EDIT++:

How to not to repeat my code in Go?

type Animal interface {
    Kingdom() string
    Phylum() string
    Family() string
}

type Wolf struct {}
type Tiger struct {}

func (w Wolf) Kingdom() string {return "Animalia"}
func (w Wolf) Phylum() string {return "Chordata"}
func (w Wolf) Family() string {return "Canidae"}

I implemented a three methods for Wolf type and I need to implement all the methods for Tiger type to implement the interface. But Kingdom and Phylum methods are the same for both types. Is it somehow possible to implement only Family method for Tiger type:

func (t Tiger) Family() string {return "Felidae"}

and not to repeat all the three methods for each type?

Disclaimer

Please don't be confused with simple string returns in the methods, in a real case I need different method implementations not just pre-defined values. Using this silly style I want to avoid of defiling your brains. So skip methods at all is not the way. Thanks

This is classical composition:

type Wolf struct {
    Animalia
    Chordata
    Canidae
}
type Tiger struct {
    Animalia
    Chordata
    Felidae
}

type Animalia struct{}

func (Animalia) Kingdom() string { return "Animalia" }

type Chordata struct{}

func (Chordata) Phylum() string { return "Chordata" }

type Canidae struct{}

func (Canidae) Family() string { return "Canidae" }

type Felidae struct{}

func (Felidae) Family() string { return "Felidae" }

func main() {
    w := Wolf{}
    t := Tiger{}
    fmt.Println(w.Kingdom(), w.Phylum(), w.Family())
    fmt.Println(t.Kingdom(), t.Phylum(), t.Family())
}

Playground: https://play.golang.org/p/Jp22N2IuHL.

This looks very much like an misuse of interfaces. Interfaces are not a replacement for classes; they're an expression of what a type can do. What you have here is data. Store data in structs.

type Animal struct {
    kingdom string
    phylum  string
    family  string
}

var wolf = Animal{"Animalia", "Chordata", "Canidae"}
var tiger = wolf
tiger.family = "Felidae"

Since I'm interested in the feature I have read a few articles about the topic and aggregated it to several reference points.

Embedding

The feature named "embedding". And it solves the issue with repeated methods implementations. Base syntax:

type Person struct {
    Name string
}

type Speaker struct { // Speaker is an abstract concept it has no name
    *Person // There is a type without field name. It is Anonymous.
}

Wrapping and decoration

Yes, there is no OOP but code must be DRY anyway. The clearest way to think about the feature is take this as wrapping structs with methods. So the most veracious way to describe anonymous fields is "decorator" pattern (well known for Pythonistas).

func (a *Speaker) Introduce(){ // But speaker can introduce itself
    fmt.Println(a.Name) // We have direct access to a wrapped struct attributes.
}

Combining and overriding

Also we can combine methods implemented on a structs

func (s Speaker) Speak() string {
    return "Blah-blah"
}

type Den struct { // Combine Person and Speaker under Den struct
    Person
    Speaker
}

func (d Den) Speak() string { // Override Speak method only for Dennis 
    return "I'm quit!"
}

func main() {
    den := Den{Person: Person{Name: "Dennis",}}
    mike := Speaker{Person: Person{Name: "Michael",}}

    fmt.Println(den.Introduce())
    fmt.Println(den.Speak())
    fmt.Println(mike.Introduce())
    fmt.Println(mike.Speak())
}

In this way we can avoid implementation of each required method for each type.

Interfaces

Same thing with interfaces. But if several interfaces are combined it means just that we don't need to declare methods which already declared in used interfaces.

Playground

Dennis Suratna's Blog article

Docs