I am about to start writing a new application and I was thinking about programming it in Go, which I have no experience with. As Go doesn't support inheritance how would I faithfully translate a domain like this into Go, while still being in accordance with the philosophy of Go?:
Maybe we could reformulate the domain like this to remove any 'is a' relationships so that it would be translatable into Go:
Would it be the best practice to model such a domain like this before translating into Go? Is it the way of thinking that the authors of Go want their users to have, when they decided to exclude inheritance in Go?
Go has just another point of view. You can think of objects and interfaces they match. It's closer to you second sentences:
A violinist has a person part, a musician part, a violin and can play the violin
This is interface Musician
- it describes any person which have method Play()
type Musician interface {
Play()
}
For exapmple structure Violinist
can have such a method:
type Violinist struct {}
func (v Violinist) Play() {}
Also Pianist
can play:
type Pianist struct {}
func (v Pianist) Play() {}
They both match interface Musician
. So you can have a musician
variable and assign different musicians to it:
var musician Musician
musician = Violinist{}
musician.Play()
musician = Pianist{}
musician.Play()
Look how the same variable changes it's bahaviour. It's the same like Polyformism and not in OOP-way, but Go-way.
When a violinist/pianist is walking in the streets, everybody can only see his person part
The same way we may define a Walker
interface - person who can walk a street and have appropriate method Walk
for it:
type Walker interface {
Walk()
}
It's a sort of duck-typing: in our life if a person can play, it can be taken to the ensemble. In Go terms if a person has method Play()
it can be assigned to a musician type variable.
Etc
Next you can make a combined interface embedding these both:
type WalkingMusician interface {
Musician
Walker
}
This describes a person which can play and walk at a moment.
var walkingMusician WalkingMusician
walkingMusician = walkingViolinist
walkingMusician.Walk()
walkingMusician.Play()