Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep code DRY in Golang

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

like image 491
I159 Avatar asked Oct 25 '16 14:10

I159


2 Answers

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"
like image 157
Rob Napier Avatar answered Oct 16 '22 00:10

Rob Napier


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.

like image 41
Ainar-G Avatar answered Oct 16 '22 01:10

Ainar-G