2

给定一些类型如下:

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

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

4

2 回答 2

1

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

它可能有用的原因示例:

  • 如果接口成员可能对某些对象有用,但对相同类型的其他实例没有用,那么这种模式可能是唯一有意义的模式。

  • 如果消费者可能持有对实现接口的各种对象的引用,其中一些支持特定成员,而另一些不支持,并且如果拥有此类集合的人可能希望在这些对象上使用该成员支持它的实例,如果所有对象都实现包括成员在内的接口,则这种用法会比有些实现而有些不实现更方便。对于接口成员来说尤其如此,IDisposable.Dispose其目的是通知它可能关心或可能不关心的事情的实现(例如,没有人需要它,它可能会在没有进一步通知的情况下被放弃),并要求它做任何它需要做的事情结果(在许多情况下没有)。盲目Dispose呼唤IEnumerable<T>比检查是否IEnumerable还实现的实现更快IDisposable。不仅无条件调用比检查IDisposable然后调用它更快——它比检查一个对象是否实现IDisposable并发现它没有更快。

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

接口包含并不总是有用的成员的最大缺点是它给实现者带来了更多的工作。因此,编写接口的人应该只包括其存在可以显着受益于几乎每个实现接口的类的至少一些消费者的成员。

于 2013-09-06T20:00:24.147 回答
0

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

OTOH,如果这是一个 API,使用 a 可能interface比 a更合适class

于 2013-09-06T19:40:00.543 回答