1

エラー コードを返す際のベスト プラクティスは何ですか?

クラス メソッドの操作が失敗する場合もありますが、例外ではありません。失敗した理由がさまざまである場合、呼び出し元に失敗した理由を伝える方法が必要です。

たとえばActor::equipItem()、RPG キャラクター オブジェクトにアイテムを装備するメソッドがあります。失敗の理由は次のとおりです。

  • キャラのレベルが足りない。
  • キャラクタークラスはそのアイテムを装備できません。
  • キャラクターの属性が足りない(力が足りないなど)。
  • 商品はすでに壊れています。
  • アイテムは両手武器で、キャラクターはすでに短剣を持っています。

私の見方では、上記の状況は例外ではありません。2 つの方法で実装できActor::equipItem()ます。

  • 1つ目は、成功した場合やレベルが十分でない場合、間違ったキャラクタークラスなどのintコードを返すことです。012
  • TRUE2 つ目はブール値またはを返し、呼び出し元がユーザーにフィードバックを提供する必要があるかどうかを検査できるようにFALSE実装します。Actor::getLastErrorCode()

OOP と API の設計に関して、2 つのうちどれがベスト プラクティスですか? 代替手段はありますか?例外的な状況ではないエラー コードを処理するためのベスト プラクティスはありますか?

4

1 に答える 1

3

私が言ったように、私は例外を投げることがこれを処理する正しい方法であるというcHaoに同意します。ただし、これらすべてのルールをどのように処理するかについてコメントしたいと思います。このシナリオは、古き良きポリモーフィズムを使用するルールエンジンに最適な状況です。(Chain of Responsibility(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;
    }
}
于 2013-03-07T03:34:42.107 に答える