I would like to know how GoLang handles code reuse without inheritances and function overrides.
Below is an example of what I am facing now. I have a code base that handles POSTing an array of an object (e.g. Apple), everything is already there: handler, service, repository, all the functions, and I need to do the same for a new object which is slightly different from previous object (e.g. Orange).
Obviously I will have to do a bunch of refactoring to avoid code duplication but don't really know how and would appreciate any help!
models.go
package project
type Fruit struct {
Property1 int64
Property2 int64
Property3 int64
Property4 int64
Property5 int64
}
type Apple struct {
Colour int64
Fruit
}
type Orange struct {
Fruit
}
apples.go
package handler
func (h Handler) ApplesPost(apples []project.Apples) {
err := validateApples(apples)
// more code
}
func validateApples(apples []project.Apples) error {
if len(apples) == 0 {
// throw err
}
for _, apple := range apples {
// do a ton of validations (one liners, function calls, etc.) on each property, including colour
}
return nil
}
oranges.go
package handler
func (h Handler) OrangesPost(oranges []project.Oranges) {
err := validateOranges(oranges)
// more code
}
func validateOranges(oranges []project.Oranges) error {
if len(oranges) == 0 {
// throw err
}
for _, orange := range oranges {
// do a ton of validations on all properties,
// pretty much exactly same as Apples validation function
// except for colour validation
}
return nil
}
Well Go does have interfaces and if you use them your code will be something like the following.
Your handler will accept a slice of the defined interface instead of concrete types.
Then you need to define
Validate()on your typesBut you won't be able to call your handler like
FruitsPost([]Apple{})(read this to see why). So You'll need a helper functions like the following to cast your slice ofAppleto a slice ofValidatable