【发布时间】:2019-04-29 15:43:22
【问题描述】:
我一直在思考这个特殊的问题,我应该如何以最干净的方式解决它。
想象一个如下所示的应用程序:
type AreaCalculator interface {
Area() int
}
type Rectangle struct {
color string
width int
height int
}
type (r *Rectangle) Area() int {
return r.width * r.height
}
type Circle struct {
color string
diameter int
}
type (c *Circle) Area() int {
return r.diameter / 2 * r.diameter / 2 * π
}
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())
}
}
这个例子显然不能编译,因为虽然 Canvas 的 String() 方法可以调用 c.Area(),但它不能访问 c.color,因为无法确保实现 AreaCalculator 的结构具有该属性。
我能想到的一个解决方案是这样做:
type AreaCalculator interface {
Area() int
Color() string
}
type Rectangle struct {
color string
width int
height int
}
type (r *Rectangle) Color() string {
return r.color
}
type (r *Rectangle) Area() int {
return r.width * r.height
}
type Circle struct {
color string
diameter int
}
type (c *Circle) Area() int {
return r.diameter / 2 * r.diameter / 2 * π
}
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())
}
}
另一种方法是尝试这样的事情:
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())
}
}
这些选项对我来说似乎都不干净。我敢肯定,有一种我想不出的更清洁的解决方案。
【问题讨论】:
-
啊,你是对的,这没有任何意义。不过这应该没什么区别吧?
-
惯用的解决方案是:重新设计。
-
是的,我的问题暗示我已经知道了。如果您已经提出建议,您将如何处理? @Volker
标签: go design-patterns