使用组合 - 如果错误的类型,应该抛出异常

时间:2012-12-17 17:06:59

标签: php oop interface composition

使用合成时,如果某个对象不属于接口类型,则应显式抛出异常。

一个例子是:

$myObject = new MyConcreteTypeA();

现在,我的界面是MyInterface

那么,我应该检查$myObjec t的类型以确保它在使用前实现MyInterface并抛出错误(如果没有)?

if (! ($myObject instanceof MyInterface)) {
    throw new Exception('Invalid type');
}

或者这只是昙花一现?

2 个答案:

答案 0 :(得分:1)

  

那么,我应该检查$myObject的类型以确保它在使用前实现MyInterface并抛出错误(如果没有)?或者这只是昙花一现?

如果你已经不遗余力地创建一个接口,并且期望对象也期望它们实现该接口,那么是的,你绝对应该检查并抱怨。

将您的方法与duck typing进行对比。在“批评”一节中,它讨论了两种不相关方法之间的混淆。我将调整他们的示例,以便它适用于PHP而不是Python *:

  

您可以轻松创建一个名为Finger的类,它希望实现press()方法的类可以执行操作。但是,名为Trousers的类也可能实现press()方法。使用Duck Typing,为了防止出现奇怪的,难以检测的错误,开发人员需要了解方法press()的每个潜在用途,即使它在概念上与他或她正在处理的内容无关。

当你尝试press()时,只有永远处理裤子绝对是至关重要的,那么你必须进行检查。如果您的代码不关心press()编辑的内容,只要 获得press(),您就可以放弃支票。

*原始示例使用属性和方法。 Python中的属性和方法共享相同的命名空间。尝试使用属性作为方法更是灾难性的,但不适用于PHP。

答案 1 :(得分:-1)

PHP不仅是dynamically typed,还是weakly typed。通过检查$myObject实现给定接口,您正在做的事情在某种程度上补充了语言中​​缺乏更结构化的键入系统。如果你想这样做,你可以,但是你可能想要考虑一些问题:

  • 您正在进行的检查将在运行时执行,因此您不会从动态类型转换为静态类型。换句话说,如果您的检查失败,它仍然会在运行时失败。
  • 如果您希望与该理念保持一致,则可能需要在整个代码中添加该类检查。然后你可以考虑转移到defensive programming style(注意:我注意到那种风格的粉丝)。
  • 您可能还想考虑PHP type hinting
  • 通过这种检查,你会反对PHP类型哲学,这几乎是duck typing

从我的角度来看,在整个代码中采用同类工作模式非常重要,因此在某些方法中放置一些分散的instanceofis_a并不是一个好习惯。如果您认为PHP类型系统不够好/安全,您可能需要考虑:

  • 如果可以,请切换到其类型系统使您更加舒适的另一种语言(例如Java或C#)。
  • 依靠其他工具,例如合并PHPUnitValidators [*],让您对代码更有信心。

HTH

[*]免责声明:我在Quanbit Research工作。