是否可以提供大部分时间未定义的API?

时间:2013-08-19 21:28:40

标签: api inheritance undefined

给出一些类型如下:

class Thing {
  getInfo();
  isRemoteThing();
  getRemoteLocation();
}

如果getRemoteLocation()返回true,isRemoteThing()方法只有定义的结果。鉴于大多数Thing不是远程的,这是一个可接受的API吗?我看到的另一个选项是提供RemoteThing子类,但是如果需要,用户需要一种方法将Thing强制转换为RemoteThing,这似乎只是增加了一个间接级别问题。

2 个答案:

答案 0 :(得分:1)

有一个接口包含可用于某些实现接口但不是所有接口的对象的成员,并且还包括一个查询方法来说明哪些接口成员将是有用的,在获得某些东西的情况下是一个很好的模式它

可能有用的原因示例:

  • 如果接口成员可能对某些对象有用,但对其他相同类型的 非常有用,则此模式可能是唯一有意义的模式。

  • 如果消费者可能持有对实现该界面的各种对象的引用,其中一些对象支持某个特定成员,而其中一些对象不支持,如果有这样一个集合的人可能需要要在支持它的那些实例上使用该成员,如果所有对象实现包括该成员的接口,则这种使用将比在某些实现的情况下更有利,而有些则不然。对于像IDisposable.Dispose这样的接口成员来说,这是尤其 true,其目的是通知实现可能或可能不关心的事情(例如,没有人需要它,并且可能会在没有进一步的情况下放弃它通知),并要求它做任何需要的事情(在许多情况下没有)。盲目地在Dispose上调用IEnumerable<T>比检查IEnumerable的实现是否也实现IDisposable更快。不仅无条件调用比检查IDisposable然后调用它更快 - 它比检查对象是否实现IDisposable并发现它没有更快。

  • 在某些情况下,消费者可能会使用字段在不同时间保存不同类型的内容。作为一个例子,有一个字段在某些时候将保持对可变对象的唯一现存引用,并且在其他时候将保持对不可变对象的可能共享引用可能是有用的。如果字段的类型包括变异方法(可能或可能不起作用)以及使用从不可变的数据复制的数据创建新的可变实例的方法,则接收对象并且可能想要变更数据的代码可以存储对传入对象的引用。如果它想要改变数据,它可以通过引用可变副本来覆盖该字段;但是,如果它永远不会变得不得不改变数据,它可以简单地使用传入的不可变对象,而不必费心复制它。

拥有接口的最大缺点包括并不总是有用的成员,它会对实施者施加更多的工作。因此,编写接口的人应该只包括成员,这些成员的存在可以使实现该接口的几乎每个类的至少一些消费者受益。

答案 1 :(得分:0)

为什么这不可接受?但是,应该清楚地记录下来。如果查看.net类库或JDK,可以使用集合接口来定义添加或删除项的方法,但是有不可修改的类实现这些接口。在这种情况下,这是一个好主意 - 正如您所做的那样 - 提供一种方法来查询对象是否具有某些功能,因为这可以帮助您避免在方法不合适的情况下出现异常。

OTOH,如果这是一个API,使用interface而不是class可能更合适。