2009-02-06 17 views
1

有一个关于在C#代码中使用函数式编程技巧的问题。例如功能样式C#API设计(返回函数参数增加了计算结果)

让我们有接口

interface IGraph { /*contains vertices and edges*/} 

假设我们需要布置图的顶点(点分配到每个顶点)。

interface ILayoutInfo { 
    Point GetVertexPoint(vertex); 
} 

简单的布局路线能有这样的签名:

ILayoutInfo SimpleLayout(IGraph graph); 

可以在这样的方式

void Demo() { 
    IGraph graph = CreateGraphInAnyWay(); 
    ILayoutInfo layout = SimpleLayout(graph); 
    PrintCoordinates(graph,layout); 
} 

被用来在下面的设计需要PrintCoordinates既引用到图形和布局。

考虑功能风格设计,其中布局布线增加图形信息 与关于图顶点coordenates的信息。

ILayoutedGraph SimpleLayoutNew(IGraph graph); 

凡ILayoutedGraph同时实现IGRAPH和ILayoutInfo

void DemoNew() { 
    IGraph graph = CreateGraphInAnyWay(); 
    ILayoutedGraph layoutedGraph = SimpleLayoutNew(graph); 
    PrintCoordinatesNew(layoutedGraph); 
} 

1)在本设计中PrintCoordinatesNew只能得到一个参数。 2)奇怪的接口ILayoutedGraph诞生了,它不包含任何方法,只是包装其他接口。如果某些图书馆有其他类型的INetwork,我们最终会创建 创建包装界面ILayoutedNetwork,ILayoutedTree(这很糟糕)。

所以这样的技术仅仅在功能语言中使用,只是因为它们不能以其他方式工作(没有状态,所以功能必须将输入与计算信息结合以供外部例程使用),或者它在命令式世界中是可行的太?

非常感谢,

PS:一个更详细的漂亮的印刷例子可以在这里找到 http://tivadj.blogspot.com/2009/02/designing-c-api-in-functional-style.html

回答

0

如果在传递两个参数时看起来有些不安,那么您的布局(ILayoutInfo)就会链接到用于生成它的图形。如果通过一个没有用于生成图形的布局来传递布局,我将毫无意义。

在这种情况下,您可以在布局信息中保留对图形的引用,并在ILayoutInfo接口上提供一个访问器。

这样,您只能传递ILayoutInfo实例,而PrintCoordinates函数仍然可以访问用于生成ILayoutInfo的图形。

如果您有其他类型的可以生成布局信息的对象,请为它们使用通用接口,或者创建ILayoutInfo通用接口。

+0

谢谢。你真的给我一口新鲜空气。 – tivadj 2009-02-07 10:32:09

0

你能实现这个使用实现两个接口的类和铸造的回报为这门课吗?

+0

的问题是什么API(接口)发布: 丹药风格 情形1)IGRAPH,ILayoutInfo和SimpleLayout(IGRAPH):ILayoutInfo 或实用的风格 案例2)IGRAPH,ILayoutedGraph SimpleLayoutNew(IGRAPH):ILayoutedGraph === = ILayoutedGraph确实可以由一些内部类实现。 – tivadj 2009-02-06 13:18:22

0

没有与你原来的

void Demo() { 
    IGraph graph = CreateGraphInAnyWay(); 
    ILayoutInfo layout = SimpleLayout(graph); 
    PrintCoordinates(graph,layout); 
} 

它是完美的功能API没有问题。一个命令式API将在创建之后涉及对的更改。例如

void Demo() { 
    IGraph graph = CreateGraphInAnyWay(); 
    graph.Layout(new SimpleLayout()); // changes the state of graph 
    PrintCoordinates(graph); 
} 

至于ILayoutedGraph,ILayoutedTree,ILayoutedQueue等的问题,我想你会在这种被允许在面向对象语言的功能语言和多重继承解决这个问题的泛型类。

就个人而言,我会推荐仿制药:ILayout<a>其中a是需要布置边缘的东西。