【发布时间】:2016-03-21 15:59:38
【问题描述】:
我正在从事计算几何项目。我有代表几何对象的类:Point、LineSegment 和对这些对象执行计算的类:Geometry。我对得墨忒耳法则和“MethodWithPointAndLineSegment”感到困惑。
class Point
{
public int X { get; set; }
public int Y { get; set; }
...
}
class LineSegment
{
public Point InitialPoint { get; set; }
public Point TerminalPoint { get; set; }
...
}
class Geometry
{
private ... MethodWithThreePoints(Point p1, Point p2, Point p3)
{
// accessing X and Y properties of passed points
...
}
public ... MethodWithPointAndLineSegment(Point p1, LineSegment segment)
{
MethodWithThreePoints(p1, segment.InitialPoint, segment.TerminalPoint);
...
}
}
我的问题是:MethodWithPointAndLineSegment 是否违反了 Demeter 法则?我想是的,因为它访问 InitialPoint 和 TerminalPoint 属性并将它们作为参数传递给MethodWithThreePoints,它访问这些点的 X 和 Y 属性。换句话说,MethodWithThreePoints 使用传递给类方法的对象属性的属性。
如果它违反了得墨忒耳法则,那么我看不到这个问题的最佳和合理的解决方案。我知道,我可以向 LineSegment 类添加额外的属性来满足 LoD:
class LineSegment
{
...
public int InitialPointX
{
get { return InitialPoint.X; }
set { InitialPoint.X = value; }
}
//etc...
}
但是当我想在MethodWithPointAndLineSegment 中调用MethodWithThreePoints 时,它会强制我创建新点:new Point(segment.InitialPointX, segment.InitialPointY)... 并将这些新点传递给MethodWithThreePoints。它引入了一些额外的和不需要的性能成本,因为我必须创建新对象并将多级访问器返回的构造函数值传递给它们。
我不确定,对于这个问题和许多类似问题,最好的解决方案是什么:满足 LoD 或便利性以及在这种情况下的性能(这些方法将在短时间内多次调用以执行算法计算) .
欢迎任何建议和解释。
【问题讨论】:
-
送LoD到地狱,当然你必须访问对象的内部对象,一个段是两个点:一个点是N个坐标(对于N维),它更容易使用 MethodWithPointAndLineSegment(Point p1, LineSegment 段)比 MethodWithThreePoints(Point p1, Point p2, Point p3)
-
令人困惑的是“法律”部分。与所有其他指南一样,它是一个指南,而且您似乎对 OOD 足够精通,可以理解在哪些情况下它更多的是一种责任而不是一种好处。
-
LoD 是关于隐藏实现细节,而不是数据结构。所以你不想要thing.subServiceX.subServiceY.doSomething()。但是 user.contactInfo.address.street 通常不被认为是违规行为;必须完全扁平化所有数据结构是愚蠢的。
标签: c# law-of-demeter