类型检查是否正常?

时间:2009-01-15 18:43:41

标签: oop inheritance interface

即使您正在检查接口,类型检查也被认为是不好的做法吗?我知道你应该总是编程到一个接口而不是一个实现 - 这是什么意思?

例如,在PHP中,以下是否可以?

if($class instanceof AnInterface) {
   // Do some code
}

或者是否有更好的方法来改变基于类类型的代码行为?

编辑:为了清楚我正在讨论检查一个类是否实现一个接口,而不仅仅是它是某个类的实例。

4 个答案:

答案 0 :(得分:5)

只要您遵循LSP,我就不会发现问题。您的代码必须与接口的任何实现一起使用。只要您能够正确使用接口的任何实现,某些实现会导致您遵循不同的代码路径,这不是问题。

如果您的代码不能与界面的所有实现一起使用,那么您不应该首先使用该界面。

答案 1 :(得分:1)

如果你可以避免类型检查你应该;然而,我觉得它很方便的一个场景是,我们有一个Web服务,它接收了一条消息,但消息的内容可能会改变。我们不得不将消息保留回db,以便获得正确的组件将消息分解为正确的表,我们在某种意义上使用了类型检查。

我发现更常见和更灵活的是if($ class instanceof SomeOtherType)例如定义一个IProcessing策略,然后使用基于$ class类型的工厂创建正确的类。

所以在c#中粗略地说:

void Process(Message msg)
{
    IProcessor processor=ProcessignFactory.GetProcessor(msg.GetType()); 
    processor.Process(msg); 
}

然而,如果您只处理一个不会改变的变体,使用类型检查实现它,并且当/如果您发现错误并且需要更多检查然后将其重构为更强大,那么有时这样做可能会有点过分溶液

答案 2 :(得分:1)

在我的实践中,对类型(以及类型转换)的任何检查总是表明代码或语言有问题。

所以我尽量避免使用它。

答案 3 :(得分:0)

在接口提供执行某些操作所需的所有方法的情况下,通常需要运行时类型检查,但是提供的操作不足以完成。这种情况的一个主要例子是确定可枚举序列中的项目数。可以通过枚举序列来做出这样的决定,但许多可枚举对象“知道”它们包含多少项。如果一个对象知道它包含多少项,那么询问它可能比通过集合枚举并单独计算项目更有效。

可以说,IEnumerable应该提供一些方法来询问它知道它包含的项目数量[知道对象可能知道该数字是无限的,或者它最多是4,591(但是可能会少很多),等等,但事实并非如此。可能理想的是,如果可以生成新版本的IEnumerable接口,其包括它添加的任何“新”方法的默认实现,并且如果这样的接口可以被认为是由当前版本的任何实现实现的。不幸的是,因为不存在这样的特性,所以获取可枚举集合的计数而不枚举它的唯一方法是检查它是否实现了包含Count成员的任何已知集合接口。