【发布时间】:2010-09-29 14:16:45
【问题描述】:
API 应该提供 Rect::contains(Point) 或 Point::is_inside(Rect) 还是两者都提供? 还是 Math::contains(Point, Rect) 导致它是对称的?
同样的 Q 也适用于 LineSegment::contains(Point)、Rect::fully_contains(Circle) 等。
【问题讨论】:
API 应该提供 Rect::contains(Point) 或 Point::is_inside(Rect) 还是两者都提供? 还是 Math::contains(Point, Rect) 导致它是对称的?
同样的 Q 也适用于 LineSegment::contains(Point)、Rect::fully_contains(Circle) 等。
【问题讨论】:
Rect::contains(Point) 最有意义,因为它是一个构建块。另一个并不是真正必要的,因为您希望每个特定的形状都可以实现该操作,而 Point 不必知道所有可能的形状。 LineSegment 的答案相同。
关于Circle 和Rect 之间的关系,使用大多数面向对象的框架更加棘手,并且没有任何明确的答案。其他一些面向对象的风格,比如 CLOS,通过使用泛型函数和方法来做到这一点,这使得它毫无疑问。
【讨论】:
完全取决于是什么让您的程序表达更清晰,更符合您要解决的问题。所以在某种程度上,以上所有内容在不同的情况下都应该没问题。
但是,总的来说,我稍微倾向于Rect::contains(Point),而不是Point::Is_inside(Rect)。那是因为我认为Point 类,因为它会被各种类(如'Circle'、'Hexagon' 等)使用,应该是非常基本的并且只包含最小接口。
Math::contains(Rect, Point) 将是我的第二选择。如果我想保持我的 Rectangle 类非常原始并且不给它添加太多“便利”功能,我会使用这种方法。
要记住的重要一点是,不要将课程的设计视为一成不变的。继续选择现在看起来最好的设计。每当您的需求发生变化时,您都可以并且应该对其进行更改。这就是所谓的refactoring。
【讨论】:
我支持 Frederick 的 Math::contains 方法,但我认为最大的缺点是开发人员在查找方法时失去了 IntelliSense 的可发现性。这是我对 Boost 和 STL 的不满之一。
Rect::contains 最终出错的一个例子是 iPhone SDK 绘制字符串的方法,基本上就是 String::drawInRect。
【讨论】:
这取决于实现,但像 Federick 一样,我也倾向于选择 Math::contains(Rect,Point),而不是 Rect::contains(Point)。这样做的原因是后者导致了一个对象层次结构,其中包括作为虚拟的 contains 成员函数,它在类之间被覆盖。在处理大量矩形和类似图元时,这可能会产生巨大的开销。
【讨论】: