例如,我将使用我的计算器对其进行标记化,然后将其转换为RPN并解决以RPN给出的问题。
在标记化步骤中,有各种无效输入,比如“7.7.8”或“^&##”,我是否应该为未知符号和无效数字分别设置异常?如果只有一个异常,然后在其中包含错误类型的方法,提供给用户,这样做是否合适?
我真的没有找到太多关于这方面的资料,所以我想问问比我更有经验的人。
-----编辑:
感谢大家的精彩回答,今天我学到了很多 :) 关于我的问题,甚至更多。
从前置条件和后置条件的角度考虑您的词法分析器。以下是两种设计词法分析器的方式:
词法分析器是一种设备,它接收一个格式良好的输入字符串并输出一个词法分析结果。输入字符串必须是格式良好的;如果不是,则词法分析器会因异常而失败。
词法分析器是一种设备,它接收一个输入字符串并产生一个词法分析结果。词法分析包括对错误条件进行识别和分析。
你是否知道你要传递的字符串是正确的,并且希望在出现异常情况时抛出异常?或者你不确定该字符串是否正确,希望词法分析器来确定呢?
对于前一种情况,请抛出异常。对于后一种情况,请将错误分析作为词法分析器输出的一部分。
基本上我想表达的是不要产生令人烦恼的异常。烦人的异常非常恼人。如果您的代码的调用者调用它来确定字符串是否正确,则他们不希望以异常形式获得该信息,而希望以表示错误分析的数据对象形式获得该信息。如果代码的目的是产生错误分析,则请将其作为该方法的正常操作产生。不要将分析嵌入异常并使某人捕获异常才能获取它。
这是一份关于在 .Net 中最佳异常处理实践的良好参考。
http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx
Parse
和TryParse
。注意,Parse
函数承诺解析一个字符串,如果无法解析(例如,因为字符串格式不正确),则抛出异常。而TryParse
承诺尝试解析,因此如果无法解析,则不会抛出异常。简而言之,如果您的函数做出了承诺却未能实现,那么您应该抛出异常。编程中的一般规则是KISS。只有在需要时才应该抛出/创建异常。如果没有人会捕获它,那么就没有必要创建整套异常。
在您的情况下,您可以:
如果您发现正在捕获异常并解析消息并采取行动,则是创建自定义异常/异常的时候了。
您可以创建具有“类型”字段的自定义异常,但任何依赖于异常的设计都是不好的。
所有的解析异常都应该至少共享一个基类,这样调用者就可以捕获任何解析异常而不必在catch子句中列出它们(并可能忘记其中一个)。
你可以走分类子类的路线,但我认为在有需要之前不必做出如此明确的区分。如果调用程序对所有解析错误采取相同的操作,则它们都可以是同一类,仅显示消息不同。如果变得清楚某些错误需要以不同方式处理,则创建一个子类。围绕使用案例进行设计。
顺便说一下:我认为如果给定方法无法实现其承诺,应该抛出异常,从而保护开发人员免于在失败的情况下假设成功。决定要做出哪些承诺是一个更大的设计问题,你可以查看现有的解析API以获取灵感。