我需要将一组函数定义为面向公众的SDK的接口的一部分,并尝试找出发送给调用者代码的最佳方式,如果某些事情成功或不成功,如果没有,为什么不呢。 / p>
我首先考虑的是回报值与例外。我想我需要将两者结合使用。错误引起的错误状态/错误的例外情况。返回值,用于函数按预期运行的时间,只想将调用结果返回给调用者。
现在,对于返回类型。我可以使用整数(旗帜)或布尔值。内部有人认为应该使用布尔值,因为它更简单,不需要旗帜。布尔限制你指定成功或失败,没有解释。
我会使用标志代替两个参数。首先,您可以返回两个以上的可能值。允许{success,fail,fail_reason_1,fail_reason_2,fail_reason_3}。请注意,由于这是用于在各种硬件设备上实现的接口,因此可能希望能够通知操作失败的原因。例如连接的设备不支持蜂鸣声,没有LCD,不支持嵌入式加密等。
谁知道未来的要求是什么。返回bool会阻止你进入,而使用标志可以让你在将来拥有更大的灵活性。那么如果将来你永远不需要超过两个值,那该怎么办呢?至少你可以选择。
考虑到这将是一个面向公众的SDK,我希望具有更大的灵活性,以防止将来发生重大变化。
由于
答案 0 :(得分:1)
在我看来,返回一个值来表示方法调用的结果和抛出异常之间的区别在于,值只是关于发生的事情的通知。应该认为方法调用是关于它定义的合同成功执行的。例如,看看如何定义boolean : Set.add()。
如果方法抛出异常,则应指示在对象/整个系统处于非法状态时不正确使用方法或调用。例如,在他的帐户没有足够的积分时尝试为用户购买东西。
异常非常适合捕获不同的失败类型:通过异常层次结构或通过向getFailureCode()
等异常添加属性或将它们组合起来。
如果必须处理失败,我会不使用标志来指示失败情况。因为忽略返回值很容易,程序员可能会错过,而异常必须被主动忽略。
答案 1 :(得分:0)
简短的回答是,根据您的域名,客户以及您提供的内容的具体情况,它会有很大差异。如果您还没有,您需要与您的客户坐下来,弄清楚他们将如何使用该库。在我的脑海中,这里有一些我正在考虑的事情:
首先,您确定的所有故障类型基本相同 - UnsupportedOperationException
,原因如此。还有其他故障类型吗?如果没有,并且您使用异常,则可能需要一个带有类型/ cause / whatever的异常类作为枚举属性。
其次,看起来很多/大多数/所有方法都会有一个或多个这样的故障类型。真的吗?如果是这样,您的API是否提供了确定设备支持的功能的任何方法?考虑一下:
// Best if I probably don't care about the result if it's not SUCCESS
final Result result = myApiObject.someMethod();
if (result == Result.BEEP_UNSUPPORTED) {
....
} else if (result == Result.NO_DISPLAY) {
....
} else if ...
和此:
// Best if I have to handle every possible failure condition, and I care what
// the failure type is
try {
myApiObject.someMethod();
} catch (final BeepUnsupportedException e) {
....
} catch (final NoDisplayException e) {
....
}
和此:
// Best if I have to consider every possible failure condition, but it probably
// doesn't matter what the failure type is
try {
myApiObject.someMethod();
} catch (final MyApiException e) {
if (Cause.BEEP_UNSUPPORTED == e.getCause()) {
....
} else ....
和此:
// Best if I know in advance what features I may need
// someMethod() may still return response codes or throw an exception. In this case
// it's possibly OK to make it a RuntimeException, since clients are expected to
// poll for features.
if (myApiObject.supports(Feature.BEEP)
&& myApiObject.supports(Feature.DISPLAY)) {
myApiObject.someMethod();
} else ...
哪一个最接近客户希望使用系统的方式?
第三,这些错误有多致命?我完全同意@Harmlezz,必须处理的失败需要是例外。没有更多信息,我们都不能告诉你的是你的失败是否需要处理。如果客户主要忽略失败(他们通常希望代码无声地失败),或者只是主要关心SUCCESS
或!SUCCESS
,那么返回代码可能没问题。如果要处理需要的失败,那么您应该抛出一个已检查的异常。您可能希望远离未经检查的异常,因为这些故障不是编程错误,并且可能由客户端正确处理。