I've been thinking alot about this particular problem I'm having an how I'm supposed to solve it the cleanest way.
Imagine an application looking like this:
type AreaCalculator interface {
Area() int
}
type Rectangle struct {
AreaCalculator
color string
width int
height int
}
type Circle struct {
AreaCalculator
color string
diameter int
}
type Canvas struct {
children []AreaCalculator
}
func (c *Canvas) String() {
for child := range c.children {
fmt.Println("Area of child with color ", child.color, " ", child.Area())
}
}
This example obviously would not compile because while the String() method of Canvas can call c.Area(), it can't access c.color since there's no way to make sure that a struct implementing AreaCalculator has that property.
One solutions I could think of was to do it like this:
type AreaCalculator interface {
Area() int
Color() string
}
type Rectangle struct {
AreaCalculator
color string
width int
height int
}
type (r *Rectangle) Color() string {
return r.color
}
type Circle struct {
AreaCalculator
color string
diameter int
}
type (c *Circle) Color() string {
return c.color
}
type Canvas struct {
children []AreaCalculator
}
func (c *Canvas) String() {
for child := range c.children {
fmt.Println("Area of child with color ", child.Color(), " ", child.Area())
}
}
The other way would be to try something like this:
type Shape struct {
Area func() int
color string
diameter int
width int
height int
}
func NewCircle() Shape {
// Shape initialisation to represent a Circle. Setting Area func here
}
func NewRectangle() Shape {
// Shape initialisation to represent a Rectangle. Setting Area func here
}
type Canvas struct {
children []Shape
}
func (c *Canvas) String() {
for child := range c.children {
fmt.Println("Area of child with color", child.color, " ", child.Area())
}
}
None of these options seem clean to me. I'm sure there's a way cleaner solution I can't think of.
Aucun commentaire:
Enregistrer un commentaire