Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
getLastErrorCode()是返回错误代码的好API设计吗?_Api_Oop_Error Handling - Fatal编程技术网

getLastErrorCode()是返回错误代码的好API设计吗?

getLastErrorCode()是返回错误代码的好API设计吗?,api,oop,error-handling,Api,Oop,Error Handling,返回错误代码的最佳实践是什么 有时我们会遇到类方法操作不成功的情况,但也不例外。如果失败的原因多种多样,那么我们需要一种方法来告诉调用方失败的原因 例如,我有一个Actor::equipItem()方法,它将一个项目装备到一个RPG角色对象。失败的原因可能是: 角色级别不够高 角色类不能装备该物品 角色属性不足(例如强度不够) 这个东西已经坏了 该物品是双手武器,角色已经在挥舞匕首 等等 在我看来,上述情况并不例外。我可以通过两种方式实现Actor::equipItem() 首先是返回in

返回错误代码的最佳实践是什么

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

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

  • 角色级别不够高
  • 角色类不能装备该物品
  • 角色属性不足(例如强度不够)
  • 这个东西已经坏了
  • 该物品是双手武器,角色已经在挥舞匕首
  • 等等
在我看来,上述情况并不例外。我可以通过两种方式实现
Actor::equipItem()

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

就OOP和API设计而言,这两种方法中哪一种是最佳实践?还有其他选择吗?是否有处理非异常情况的错误代码的最佳实践?

正如我所说,我同意cHao的观点,抛出异常是正确的处理方法。不过,我想谈谈您可能决定如何处理所有这些规则。对于规则引擎来说,这个场景是一个完美的场景,使用良好的ol'多态性。(查看责任链(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;
    }
}
List equipRules=GetEquipRules();//这就是CoR模式的用武之地
foreach(equipitemrule中的IEquipItemRule规则)
{
//注意:你可以收集所有的垃圾,而不是立即扔掉
//并返回所有失败原因。
如果(!rule.CanEquip()){抛出新的适当异常(rule.Message);}
}
这样做的好处是,可以使用自己的方法进行检查。因此,如果您想先检查此方法是否成功,消费者可以调用上面的代码。当实际方法运行时,它也可以调用此检查代码

注意:设备规则的示例可能如下:

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;
    }
}
公共类CharacterLevelRule:IEquipItemRule
{
公共图书馆
{

如果(characterLevel)如果你正在修改对象图,然后发现潜在的图是无效的,我会称之为非常例外。就我个人而言,我会将装备一个项目的过程分解为签入是否可以,然后再执行。这意味着实现
Actor::canEquip()
,我想这意味着将
int
错误代码返回给调用者。那么第一个是你的方法吗?我想是的。尽管我有
equipItem()
如果物品无法配备,则抛出异常。如果调用方不希望出现异常,它可以事先检查,如果它不介意,它仍然可以使用
canEquip
或异常来找出问题所在。我同意@cHao。如果一个方法不能做到它所说的,那就是异常。如果你需要知道原因,您可以捕获相应的异常。对于需要外部信息的规则,您将需要提供它,但信息是不同的。它可以是字符级别(int)、类类型(object),一个关于角色是否装备了副手武器的bool,等等。因此我不确定将其分解为严格的接口是否是一个好的解决方案。但是我同意您的观点,将其分解为两个方法,以便可以独立调用检查方法。各种信息都可以。您可以将其传递到CanEquip()中方法。这就是为什么传递整个对象而不是片段被视为良好实践的原因。例如,发送角色而不仅仅是他的级别。这样,每个规则都可以选择它需要做决定的内容。如果你需要多个片段来做决定,那么这些片段可以包装在一个容器中,因此你仍然只传递一个对象(或很少对象)。经过一些思考,我认为你们在这方面都是正确的。可能有这样的情况,即在操作更合适之后检查操作是否成功(即
getLastErrorCode()
),但使用check方法可以提供更大的灵活性,对我来说,这意味着它是一种更好的API设计。我正在考虑创建一个
InventoryException
类,该类包含错误代码,并充当在库存操作(装备、放置、移动、移除、添加)中抛出的异常。