2009-01-15 61 views
1

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

例如,在PHP中,以下是OK吗?

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

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

编辑:只是要清楚我说的是检查类是否实现了接口不仅仅是它是有一定的类的实例。

回答

5

只要你按照LSP,我没有看到一个问题。您的代码必须与接口的任何实施一起使用。只要您可以正确地使用接口的任何实现,某些实现会导致您遵循不同的代码路径,这不是问题。

如果您的代码不适用于该接口的所有实现,那么您不应该首先使用该接口。

+0

这是一个很好的观点,但是如果您进行类型检查,则很容易让自己陷入每次添加新子类时必须更新方法的情况。应该避免使用多态性。 – 2009-01-15 19:05:54

+0

当然,只要子类实现了接口,那么就不需要做任何修改? – 2009-01-15 19:10:06

1

如果你可以避免类型检查你应该;然而,我发现它很方便的一种情况是,我们有一个Web服务,它接收到一条消息,但消息的内容可能会改变。我们必须将消息持久保存到数据库中,以便获得正确的组件,将消息分解为适当的表,我们在某种意义上使用类型检查。

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

所以在C#中大致是这样的:

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

但有时这样做可能是矫枉过正,如果你只用一个变体处理,不会更改使用类型检查实现它,而当/如果你发现你是错误的,它需要更多的检查,然后将其重构为更强大的解决方案。

1

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

所以我尽量避免它。

+0

如何在没有类型转换的情况下高效地确定可枚举集合中的项目数? – supercat 2013-04-16 15:45:13

0

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

可以说,IEnumerable应该提供了一些方法来询问它知道它包含的项目的数量[认识到对象可能知道这个数字是无界的,或者它至多是4,591(但可能是一个少得多)等],但它不。如果可以生成一个新版本的IEnumerable接口,其中包括它添加的任何“新”方法的默认实现,并且这种接口可以被认为是由当前版本的任何实现来实现,那么可能是理想的。不幸的是,因为没有这样的功能存在,唯一能够枚举枚举集合的计数的方法是检查它是否实现了包含Count成员的任何已知集合接口。