I'd like to know if one may prefer the use of either reflection or interface definition versus the other. I am particularly interested in tradeoff between lines of code written and the performance of a system.
Let me illustrate the particular case that plagues me. There are multiple structures that contain some mandatory fields, and some optional fields.
type Common struct {
X int
Y string
}
type A struct {
common Common
optionalA OptionalA
}
type B struct {
common Common
optionalB OptionalB
}
Approach 1: Using reflect (as many functions as parameters in Common):
//obj is A or B type or any other type for that matter
func GetX(obj interface{}) (int, bool) {
reflectData := reflect.ValueOf(obj).Elem()
if reflectData.IsValid() == false {
return 0, false
}
myCommon := reflectData.FieldByName("common").Interface().(Common)
return myCommon.X, true
}
func GetY(obj interface{}) (string, bool) {
reflectData := reflect.ValueOf(obj).Elem()
if reflectData.IsValid() == false {
return "", false
}
myCommon := reflectData.FieldByName("common").Interface().(Common)
return myCommon.Y, true
}
Approach 2: Using interfaces (as many functions as parameters in Common * Number of possible objects):
type SomeInterface interface {
GetX() int
GetY() string
}
func GetXFromCommon(c Common) int {
return c.X
}
func GetYFromCommon(c Common) string {
return c.Y
}
func (obj A) GetX() int {
return GetXFromCommon(obj.common)
}
func (obj B) GetX() int {
return GetXFromCommon(obj.common)
}
func (obj A) GetY() string {
return GetYFromCommon(obj.common)
}
func (obj B) GetY() string {
return GetYFromCommon(obj.common)
}
Similar code duplication for for all common fields and all possible objects. Fairly straightforward, no complexity like in the case of reflection, and perhaps faster processing times. However, all that duplicate code and code-maintainability problems! Imagine if there were 100s of such structures to deal with, and lot more parameters in Common.
Aucun commentaire:
Enregistrer un commentaire