-2

我正在 C# 中创建半边数据结构的实现。这个结构的细节与我的问题无关,所以我只会尽可能深入地介绍它,但如果有人感兴趣,可以在Flipcode上找到一个简短的摘要。

我的数据结构的面向对象表示由 4 个类组成:Halfedge、和Edge,它们相互包含一些相互引用。(特别是:每条半边引用一个顶点,而每条边、顶点和面都引用一个半边。)处理和维护这种低级表示是一项艰巨的任务,因此它的修改不应该暴露给代码的用户,以保证数据结构的一致性。VertexFace

为了实现这一点,我创建了第 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对象需要操纵包含的HalfedgeEdgeVertex对象的内部状态Face,以根据用户给出的输入构建和维护数据结构。然而,如果这 4 个类有public方法(或属性)来改变它们的状态,那么对用户隐藏表示的整个想法就被破坏了,因为它们可以被用户直接调用。(可惜C#现在没有朋友类的概念。)

如果我将HalfedgeEdgeVertexFace嵌套在里面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,而不是为其他类。可访问性不好,因为它会为整个程序集公开这些功能。VertexFaceGraphInternal

我应该为它们创建“只读”包装类吗,因为 .NET 中的许多集合都有一个只读包装(如List<T>),并且在返回对象时只为用户公开那些(例如AddFace())?

4

2 回答 2

2

为什么不对每种类型都使用一个接口并将它们暴露给外界:

public interface IHalfedge
{
}

public interface IEdge
{
}

public interface IVertex
{
}

public interface IFace
{
}

public class Graph
{
    private class Halfedge : IHalfedge
    { /* ... */
    }

    private class Edge : IEdge
    { /* ... */
    }

    private class Vertex : IVertex
    { /* ... */
    }

    private class Face : IFace
    {/* ... */
    }

    // Cannot return a Face, since it is not public.
    public IFace AddFace(/* params about the vertexes of the face to create */)
    {
        /* Algorithm to create halfegdes, edges, vertices and a face */
    }
}

这样你就可以隐藏你的类Graph

于 2014-05-06T14:13:46.990 回答
1

您是否考虑过让您的类保持私有,但提供只公开您想要的公共接口?这具有隐式实现的优点(如果您保持所有成员名称相同,则不必编写大量额外代码,超出接口定义本身)。另外,请记住,类中的读写属性可以隐式实现接口中的只读属性。

于 2014-05-06T14:15:11.430 回答