我正在研究图形实现。我的 Graph 类如下所示:
public class Graph<VERTEX_TYPE, EDGE_TYPE, IDENTIFIER_TYPE>
where VERTEX_TYPE : Identifier<IDENTIFIER_TYPE>
where EDGE_TYPE : Identifier<IDENTIFIER_TYPE>
where IDENTIFIER_TYPE : IConvertible
{
...
}
(请不要关心实现的接口,它们与问题无关)。
Vertex 和 Edge 类都包含一些可以通过这种方式访问的通用数据:
public class Vertex<VERTEX_TYPE,EDGE_TYPE,IDENTIFIER_TYPE>
where VERTEX_TYPE : Identifier<IDENTIFIER_TYPE>
where EDGE_TYPE : Identifier<IDENTIFIER_TYPE>
{
public VERTEX_TYPE Data{get;private set;}
....
}
public class Edge<EDGE_TYPE,VERTEX_TYPE,IDENTIFIER_TYPE>
where EDGE_TYPE : Identifier<IDENTIFIER_TYPE>
where VERTEX_TYPE : Identifier<IDENTIFIER_TYPE>
{
public EDGE_TYPE Data{get;private set;}
....
}
现在我有一个实现一些算法的 GraphVisitor 类。当遍历图形时,我希望在算法当前遍历的边和顶点上调用一些代表。
我定义了 2 对代表,一对与必须在图形元素上执行的操作有关,例如Vertex<VERTEX_TYPE,EDGE_TYPE,IDENTIFIER_TYPE>
. 第二对委托与仅对持有的数据执行的操作有关。
public class GraphVisitor<VERTEX_TYPE, EDGE_TYPE, IDENTIFIER_TYPE>
where VERTEX_TYPE : Identifier<IDENTIFIER_TYPE>
where EDGE_TYPE : Identifier<IDENTIFIER_TYPE>
where IDENTIFIER_TYPE : IConvertible
{
public delegate void VertexDataOperation(VERTEX_TYPE vertex);
public delegate void EdgeDataOperation(EDGE_TYPE vertex);
public delegate void VertexOperation(Vertex<VERTEX_TYPE,EDGE_TYPE,IDENTIFIER_TYPE> vertex);
public delegate void EdgeOperation(Edge<EDGE_TYPE,VERTEX_TYPE,IDENTIFIER_TYPE> vertex);
.....
}
我已经实现了 BFS 算法(我避免发布整个实现),将两个委托作为参数:
public void BFS(VertexOperation op, EdgeOperation edgeOp)
{
...
Vertex<VERTEX_TYPE,EDGE_TYPE,IDENTIFIER_TYPE> currentVertex;
op(currentVertex);
foreach (Edge<EDGE_TYPE,VERTEX_TYPE,IDENTIFIER_TYPE> e in currentVertex.NeighBors())
{
edgeOp(e);
...
}
...
VertexDataOperation
我正在尝试为and编写 BFS 版本EdgeDataOperation
,当我意识到我最终应该复制所有 BFS 代码以使用 2 个不同的委托参数类型时:
public void BFS(VertexDataOperation op, EdgeDataOperation edgeOp)
...
Vertex<VERTEX_TYPE,EDGE_TYPE,IDENTIFIER_TYPE> currentVertex;
op(currentVertex.Data); //method differs only here
foreach (Edge<EDGE_TYPE,VERTEX_TYPE,IDENTIFIER_TYPE> e in currentVertex.NeighBors())
{
edgeOp(e.Data);//method differs only here
...
}
我想避免相同方法的相同实现。唯一改变的是方法签名和调用该方法的对象。
有没有人有任何想法来改进这段代码的设计?
编辑:
我可以将所有 4 个委托传递给一个函数,但在每次遍历期间我只会使用其中的一对,所以它看起来不太干净。