我正在 C# 中创建半边数据结构的实现。这个结构的细节与我的问题无关,所以我只会尽可能深入地介绍它,但如果有人感兴趣,可以在Flipcode上找到一个简短的摘要。
我的数据结构的面向对象表示由 4 个类组成:Halfedge
、和Edge
,它们相互包含一些相互引用。(特别是:每条半边引用一个顶点,而每条边、顶点和面都引用一个半边。)处理和维护这种低级表示是一项艰巨的任务,因此它的修改不应该暴露给代码的用户,以保证数据结构的一致性。Vertex
Face
为了实现这一点,我创建了第 5 个Graph
类以在它们之上提供更高的抽象层。这个想法是代码/库的用户只需要与Graph
实例通信来构建或查询拓扑模型,而不必处理半边、边、顶点和面的低级关系;因此他们不能破坏它。
现在来解决问题。面、顶点、边和半边都需要可从Graph
. 半边数据结构包含有关数据的拓扑信息,因此请求例如给定面或边的相邻面是一种资源高效的查询。如何使用这些类的示例:
Graph graph = new Graph();
Face face = graph.AddFace(/* params about the vertexes of the face to create */);
// More data given to the graph ...
// Later:
Face[] faces = face.AdjacentFaces;
Vertex[] vertixes = face.BoundaryVertices;
出于显而易见的目的,Graph
对象需要操纵包含的Halfedge
、Edge
和Vertex
对象的内部状态Face
,以根据用户给出的输入构建和维护数据结构。然而,如果这 4 个类有public
方法(或属性)来改变它们的状态,那么对用户隐藏表示的整个想法就被破坏了,因为它们可以被用户直接调用。(可惜C#现在没有朋友类的概念。)
如果我将Halfedge
、Edge
和Vertex
类Face
嵌套在里面Graph
并且不将它们公开,那么就不可能为用户检索这些类型。例如:
public class Graph
{
private class Halfedge { /* ... */ }
private class Edge { /* ... */ }
private class Vertex { /* ... */ }
private class Face { /* ... */ }
// Cannot return a Face, since it is not public.
public Face AddFace(/* params about the vertexes of the face to create */)
{
/* Algorithm to create halfegdes, edges, vertices and a face */
}
}
所以基本上我的问题是最好遵循什么设计来实现这样的数据结构。、Halfedge
和类需要公开一个接口来为类修改它们 Edge
,而不是为其他类。可访问性不好,因为它会为整个程序集公开这些功能。Vertex
Face
Graph
Internal
我应该为它们创建“只读”包装类吗,因为 .NET 中的许多集合都有一个只读包装(如List<T>
),并且在返回对象时只为用户公开那些(例如AddFace()
)?