如何区分“角色”界面和“结果”界面?

时间:2014-10-17 16:24:06

标签: c# oop interface

这个问题经常出现在我的编码中,我很惊讶我能找到很少的参考,并且会重视其他人的想法和想法。

我为我所使用的框架以及我想要分解的大型域模型定义了许多API。这些API几乎完全由接口组成(在我的例子中,意思是C#接口)。我一遍又一遍地发现,我想区分两种界面。在没有找到任何更广泛使用的术语的情况下,我将这两个定义如下:

  • '角色'接口旨在由API外部的对象实现,以便这些对象可以用作API上定义的方法的参数。

  • '结果'接口由API内的对象实现,并通过API提供给系统的其他部分。定义结果接口而不是公开实现它的对象的目的是将对象的视图限制到外部世界。

举一个例子,Payments子系统可能将IPayableItem定义为Role接口,由应用程序的其他部分中的许多类型实现,以便为它们生成Payments。那些生成的Payment对象可以通过API检索,但由Result接口IPayment定义。

我目前唯一可以区分这些的方法是命名约定和/或注释。理想情况下,我希望语言强制执行区分,并强制执行规则:您不能在API之外实现Result接口,只能使用它。但是C#没有提供任何这样的机制。 (任何人都可以告诉我一种语言吗?)。我可以定义一个属性,但这仍然不会强制执行任何操作。

区别的另一个重要意义在于API的语义版本控制。如果我将一个新成员添加到Role接口,那么这应该被视为一个重大变化(因此是一个第一级版本) - 因为任何现有的外部实现都需要添加该成员。但是,如果我将一个成员添加到我认为是“结果”界面,那么它应该只是我自己的代码受到影响 - 它只是一个新功能(二级版本)供其他人使用。但是由于两种类型之间没有强制区分,因此人们实施Result接口存在一些风险,因此他们的代码将被破坏。

还有其他人遇到过这种困境吗?如果是这样,你是如何处理它的?我期待着你的回答。

但请不要两者都回答以下任何一个论点(我经常听到):

  • 我的Result接口应该是抽象类而不是接口。这并没有解决问题,并且可能使情况变得更糟,因为外部代码可以对它们进行分类。

  • 我应该返回具体类型并确保我不想在API之外访问的任何内容都标记为“内部”。在很多情况下我需要API中的内容公开,例如可供其他框架访问(不通过API)。

1 个答案:

答案 0 :(得分:1)

我认为您所要求的是可以公开界面,但确定给定的实例是您创建的实例?

如果是这样,您还可以创建内部私有接口,并将所有实现标记为也实现私有接口。然后在从外部世界获得对象时,验证它是否也具有内部接口实现。

public interface IPublic
{
    ...
}

internal interface ISecret { }

public class PublicImplementation : IPublic, ISecret
{
    ...
}

只有你可以实现ISecret,所以即使有人实现了IPublic并将其传递给你,它也将无法通过ISecret测试。