快速业务通道

诊断Java代码: Impostor Type错误模式 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-19
会报错。事实上,在很多情况下,返回值看起来都好象是完全合理的数字。即使我们插入些冗余代码,检查 else分句中的隐含条件是否包含(比如说,断言),也要到代码执行时才能发现错误。

很多其它相似的错误也可能在上述代码中产生。 if-then-else 代码块可能会偶尔遗漏一句分句,导致类型与那句分句相对应的所有 Form 都被错误地处理了。此外,因为 impostor type 在字段中只是一个 String ,所以它可能会被意外或恶意地修改。

无论用哪一种方法,这样的修改会带来各种各样的损害。

治疗和预防措施

正如您可能设想过的那样,我建议用类型系统在静态检查期间将它们清除,从而避免这种类型的错误。请考虑这种新颖的实现方法:

清单 3. 用实际类型实现 form

public abstract class Form {    double scale;    public Form(double _scale) {      this.scale = _scale;    }    public abstract double getArea(); } class Square extends Form {    public Square(double _scale) {      super(_scale);    }    public double getArea() {      return scale * scale;    } } class Circle extends Form {    public Circle(double _scale) {      super(_scale);    }    public double getArea() {      return Math.PI * scale * scale;    }  } class Triangle extends Form {    public Triangle(double _scale) {      super(_scale);    }    public double getArea() {      return scale * (scale * Math.sqrt(3) / 4);    } }

诊断Java代码: Impostor Type错误模式(3)

时间:2011-02-12 IBM Eric E. Allen

现在考虑一下,在创建一个新 Form 时,如果误输入了“Sqaure”,会发生什么情况。编译器将会报错,告诉我们类 Sqaure 找不到。代码将连运行的机会也没有。

同样地,编译器将不会允许我们忘记为我们的任意子类定义 getArea() 方法。当然,任何对象要改变 Form 的类型是不可能的。

最后说明

在离开这个主题之前,我还想讨论另一种可能的实现,一种我曾经讨论过的两种实现方法的混合。

在这种情况下,不使用 impostor type,但代码包含很多相同的易受性,似乎它们以前就有。实际上,这种实现方法比对每个类型单独实现 getArea() 方法 更差。

清单 4. 一种混合的实现方式

public abstract class Form {    double scale;    public Form(double _scale) {      this.scale = _scale;    }    public double getArea() {      if (this instanceof Square) {        return scale * scale;      }      else if (this instanceof Circle) {        return Math.PI * scale * scale;      }      else { // this instanceof Triangle        return scale * (scale * Math.sqrt(3) / 4);      }    } } class Square extends Form {    public Square(double _scale) {      super(_scale);    } } class Circle extends Form {    public Circle(double _scale) {      super(_scale);    } } class Triangle extends Form {    public Triangle(double _scale) {      super(_scale);    } }

尽管编译器仍旧会捕获类型的拼写错误,且对象类型是无法改变的,我们又一次使用了 if-then-else代码块调度适当的类型。这样,我们又要面临 if-then-else代码块中 instanceof检查与我们所操作的那组类型不匹配的情况。

还必须提出,像第一种实现方法那样,这个实现方法的扩展性不如第二种。

总结

那么,简而言之,这就是我们最近的错误模式:

模式:I

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号