假设我有一个方法可以在线发布一些内容并返回表示成功/失败的真/假。
但是,我的方法可能会在不同的步骤失败,例如:
我仍然希望方法只返回一个布尔值,我也不喜欢让方法抛出异常的想法,每个调用者都必须将它包装在try / catch中(我讨厌try / catch,它是总是丑陋的。)
这个问题有标准解决方案吗?
我想出的最佳解决方案是让它返回枚举而不是可能的结果,然后调用者将有一个switch语句。有没有比这更好的解决方案?
编辑:我应该更清楚;这是一个Android应用程序,用户将在线发布评论,不同的错误将被翻译成用户的消息,例如“垃圾邮件,在尝试重新发布之前等待”答案 0 :(得分:3)
返回enum
很好。但是,如果你要从很多地方调用它,那么你将在多个领域(即相同的switch
语句中)拥有相同的错误处理代码。
也许一种方法是返回一个布尔值,但在错误处理程序中封装特定的错误处理逻辑。所以你要定义一个这样的界面:
interface PostErrorHandler {
void handle(...);
}
然后你可以有具体的实现:
public class SpamErrorHandler implements PostErrorHandler {
@Override
public void handle(...) {
... //code to deal with spam
}
}
您要发布的方法的签名将是:
public boolean post(String content, PostErrorHandler handler) {
...
}
然后,您可以在handler.handle(...)
内根据错误致电post
。
如果您仍想传达发生的错误,可以使用您提到的方法:返回枚举而不是布尔值。
就异常而言,不仅仅是丑陋,在这里使用异常的主要原因是一个坏主意是看起来这些错误是预期的。如果是这样,您希望调用者以某种方式处理它们,它们似乎是您业务逻辑的一部分。但是使用异常并不是这些错误的正确方法。您通常只想在发生意外情况时才使用例外。如果必须抛出异常,那么最好使用某种状态检查/检查方法检查输入,以便在输入错误时提醒您。在这种情况下,您可以抛出异常(使其取消选中),因为情况是意外的,因为您希望调用者在调用方法之前使用状态检查方法。
答案 1 :(得分:0)
Enum可能有效,但由于您的方法将“在线发布一些内容”,因此可以考虑使用HTTP响应代码作为指南。
如果不详细了解multitude of HTTP response codes,请知道,对于您的示例:
您可以从方法中返回一个整数。然后将成功定义为返回码mod 100小于4.
希望这有帮助。
答案 2 :(得分:0)
你应该克服对try / catch的非理性仇恨。并非所有调用者都必须在try / catch中包装调用;它可以根据需要在代码的各个层面上明智地完成;例如,只有应用程序的最高级别需要担心捕获内存不足和#34;或者"磁盘已满"例外。同时try / catch构造可以与其他关键字(例如finally
)一起使用,您将可以访问嵌套异常和堆栈跟踪,并且整体将具有更丰富的调试体验。
另一方面,如果您只是想要一个布尔值,那么CLR中使用的命名模式非常常见。您提供了两个基本相同的功能。
try
{
string output = MakeSomeFunctionCall(input);
}
catch
{
}
...有时会补充一个伙伴函数,该函数执行相同的操作但返回一个布尔值,例如
string output;
bool success = TryMakeSomeFunctionCall(input, out output);
这使得调用者可以选择使用try / catch(如果需要详细的错误信息)或使用"尝试*"方法(如果不需要详细的错误信息)。
使用此模式,其他人应该清楚代码中发生了什么。
答案 3 :(得分:0)
我非常坦率地说“有一个[非常好的] 理由为什么我们开始'抛出异常'而不是'使用返回代码'。”
“返回代码”方法的基本问题是每个客户端必须通过每次调用来解释并正确处理每个 >返回代码。
......此外,它有义务做所有这一切,即使(“几乎总是如此......”)没有出错。
当一个库“抛出异常”时,客户端不必 test 来查看请求是否成功。 (“如果我们还活着,那么它就成功了。”)客户现在可以catch
它可以预见的特定的例外,同时允许任何联合国 - “冒泡”到外层处理程序的例外情况。
我诚恳地建议该战略中有智慧。 。 。