2014-01-16 105 views
0

我认为接口不仅是一组成员,而且也是强制实现保持接口文档中指定限制的“合同”。例如:交叉接口合同

interface IDevice 
{ 
    bool IsActive { get; } 

    int Address { get; } 

    /// <summary> 
    /// Raised when (IsActive == false) 
    /// and device was activated 
    /// </summary> 
    event Action Activated; 

    /// <summary> 
    /// Raised when (IsActive == true) 
    /// and device was deactivated 
    /// </summary> 
    event Action Deactivated; 

    /// <summary> 
    /// Raised when (IsActive == false) 
    /// and Address was changed 
    /// </summary> 
    event Action<int> AddressChanged; 
} 

而且我有没有兴趣激活/停用过程,但想知道什么时候Address会发生变化,因此,铅通过ISP,我创建了一个新的接口用户:

interface IAddressee 
{ 
    int Address { get; } 

    /// <summary> 
    /// Raised when Address was changed 
    /// </summary> 
    event Action<int> AddressChanged; 
} 

现在IDevice样子:

interface IDevice : IAddressee 
{ 
    bool IsActive { get; } 

    /// <summary> 
    /// Raised when (IsActive == false) 
    /// and device was activated 
    /// </summary> 
    event Action Activated; 

    /// <summary> 
    /// Raised when (IsActive == true) 
    /// and device was deactivated 
    /// </summary> 
    event Action Deactivated; 
} 

正如你看到的,IDevice的合同已经松动一个条件:AddressChanged事件只能在设备未激活时才会提升(IsActive == false)。

我不能在IAddressee接口中记录它,因为它不依赖于IDevice,并且可能存在非设备实现。

这种情况是否正常?你会怎样强迫IDevice实现正确的行为?

我的新合同的概念,所以请打消我的幻想和疑惑

+0

你只是问如何评论接口,所以有人知道他们是如何工作的?我问的原因是因为除了有关IDevices的AddressChanged特殊条件的评论之外,您还没有失去任何其他内容。在任何情况下都没有任何事情可以“强制”实施按照您的要求行事。但是也许你可以在你的AddressChanged事件处理程序中有一个“Debug.Assert(!sender is IDevice || sender.IsActive)”。 – Aaron

+0

好吧,评论是告诉合同实现的唯一方法,所以是的,我在问如何评论它。但我也想知道我是否以正确的方式思考它。我想,改变所有处理程序是一个坏主意。 – astef

+0

我认为答案是“我该如何评论这个?”真的很主观。我想我会把评论贴近IDevice声明,因为“:IAddressee”是相关的部分。但是,你真的预计有实现IAddressee而不是IDevice的对象吗?如果你不这样做,我会认为离开IDevice,因为它是更好的,无论如何。您的IDevice侦听器无需为激活/禁用注册处理程序。换句话说,除非你有实现IAddressee的非IDevice对象,否则我认为你没有通过分解AddressChanged获得任何东西。 – Aaron

回答

1

在这种情况下,抽象的条件就行了。他们表达了一些可能取决于顶级课程中没有的信息。该条件稍后以适合特定后代的方式实施。在您的例子

interface IAddressee 
{ 
    int Address { get; } 

    /// <summary> 
    /// Can Address be changed? 
    /// </summary> 
    bool IsAddessChangeable { get; }; 

    /// <summary> 
    /// Raised when (IsAddessChangeable == true) 
    /// and Address was changed 
    /// </summary> 
    event Action<int> AddressChanged; 
} 

在实现IDevice类,查询IsAddessChangeable将返回IsActive == false,在其他类别 - 根据所需的语义值。

+0

起初,我认为这违反了ISP,因为“IAddressee”必须依赖于它不使用的成员:“IsAddessChangeable”。但随后我将所有事件都改为方法,一切都变得清晰。由于AddressChanged合同,“IAddressee”用户确实依赖于“IsAddessChangeable”。我建议你用事例扩展你的答案,用事件替换方法(参见编辑) – astef

+0

@astef我回滚了你的编辑,因为这是对接受答案中代码的重大改变。我建议你先从作者那里得到关于你的编辑的反馈,或者发表一个单独的答案。 –