getLastErrorCode()是否是用于返回错误代码的良好API设计?

时间:2013-03-07 03:02:59

标签: api oop error-handling

返回错误代码的最佳做法是什么?

有时候我们会遇到类方法操作不成功的情况,但不是例外。如果它失败的原因是多种多样的,那么我们需要一种方法来告诉调用者它失败的原因。

例如,我有Actor::equipItem()方法,它将项目装备到RPG角色对象。失败的原因可能是:

  • 字符级别不够高。
  • 角色类无法装备该项目。
  • 字符属性不足(例如强度不够)。
  • 该项目已经破损。
  • 该物品是双手武器,角色已经挥舞着匕首。

我认为,上述情况并非例外。我可以通过两种方式实施Actor::equipItem()

  • 首先返回int代码,例如0代表成功,1代表级别不够,2代表错误字符等等。
  • 第二个是返回布尔值TRUEFALSE,并实现调用者可以检查是否需要向用户提供反馈的Actor::getLastErrorCode()

在OOP和API设计方面,哪两个是最佳实践?还有替代品吗?是否有处理非特殊情况的错误代码的最佳实践?

1 个答案:

答案 0 :(得分:3)

就像我说的那样,我同意cHao的说法,抛出异常是解决这个问题的正确方法。但是,我想评论您如何决定处理所有这些规则。这种情况对于规则引擎来说是一个完美的情况,使用了良好的多态性。 (检查责任链(CoR)设计模式对此有利。)

您可以在方法中使用一堆if语句。或者,更好的是,每个if检查都是它自己的类,它实现了像IEquipItemRule这样的东西:

public interface IEquipItemRule
{
    bool CanEquip();
}

然后,您的消费代码可以处理所有这样的规则,而不是if语句:

List<IEquipItemRule> equipRules = GetEquipRules();  // This is where the CoR pattern comes in

foreach (IEquipItemRule rule in equipRules)
{
    // Note: Instead of throwing immediately, you could collect all of the
    //       messages and return all of the failure reasons.
    if (!rule.CanEquip()) { throw new AppropriateException(rule.Message); }
}

关于这个的好处是这个检查可以在它自己的方法中。因此,如果您想首先检查此方法是否成功,消费者可以调用上面的代码。当实际方法运行时,它也可以调用此检查代码。

注意:设备规则的示例可能是这样的:

public class CharacterLevelRule : IEquipItemRule
{
    public bool CanEquip()
    {
        if (characterLevel <= necessaryLevel) { return false; }
        return true;
    }
}