我想知道 GoLang 如何在没有接口和函数覆盖的情况下处理代码重用。 下面是我现在面临的一个例子。我有一个处理
POST
对象数组(例如 Apple
)的代码库,一切都已经存在:处理程序、服务、存储库、所有功能,并且我需要对一个新对象执行相同的操作与之前的对象略有不同(例如 Orange
)。
显然,我必须进行大量重构以避免代码重复,但我真的不知道如何做,并且希望得到任何帮助!
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
}
Go 确实有接口,如果你使用它们,你的代码将类似于以下内容。
您的处理程序将接受定义的接口的一部分,而不是具体类型。
type Validatable interface {
Validate() error
}
func FruitsPost(fruits []Validatable) {
for _, f := range fruits {
err := f.Validate()
fmt.Println(err) // handle the error however you desire
}
// more code
}
然后你需要在你的类型上定义
Validate()
func (a Apple) Validate() error {
// do a ton of validations (one liners, function calls, etc.) on each property, including colour
return nil
}
func (o Orange) Validate() error {
// do a ton of validations (one liners, function calls, etc.) on each property, including colour
return nil
}
但是您将无法像
FruitsPost([]Apple{})
那样调用您的处理程序(请阅读 this 了解原因)。
所以你需要一个像下面这样的辅助函数来将你的 Apple
切片转换为 Validatable
切片
func CastToFruits[T Validatable](fruits []T) []Validatable {
result := []Validatable{}
for _, f := range fruits {
result = append(result, f)
}
return result
}