11

エラーコードを返すライブラリを使用しているとしましょう。ライブラリのラッパーを作成し、コード内の例外でエラーを処理したいと考えています。

ライブラリがまだ他の誰かによって開発中であり、エラー コードが変更される可能性がある場合 (新しいコードが存在する可能性がある、廃止されたコードが存在する可能性がある、または一部のエラー コードの意味がわずかに変わる可能性がある)、これを処理するための解決策は何ですか?

これが私が今いる状況です。私の場合、ライブラリは C++ で記述されており、C# を使用しています。ライブラリのコーダーは、エラー コードが変更される可能性があると述べており、それを処理する方法を見つけなければなりません。

私たちの最初の解決策は次のとおりです。

  1. さまざまなカテゴリ (最終的なもの、入力エラーなど) のエラー コードを含む XML ファイルを作成します。
  2. Wrapper は起動時にこれらのエラー コードを取得します。
  3. エラー コードのカテゴリをチェックして、適切な例外をスローします。

メソッドがエラー コード 100 を返し、ラッパーがエラー コードのカテゴリをチェックするとします。端末エラーの場合は端末エラー例外をスローし、ユーザー入力エラーの場合はユーザー入力エラー例外をスローします。

これはうまくいくはずですが、これは最適な解決策ではないように感じます。適切に記述されたエンタープライズ ソフトウェアがエラー コードの変更をどのように処理するかを知りたいです。

何をすることをお勧めしますか?

編集:エラーコードが変更されるという事実と、ライブラリのコーダーがコードが開発中であると述べているという事実については、すでに疑問を呈しています。これはアルゴリズムであり、独自の研究であるため、アルゴリズムの動作方法も変化します (彼はそれについて博士号を書いています)。したがって、彼は、さまざまなエラーが存在する可能性があるか、将来的には無関係になる可能性があると述べています.

4

5 に答える 5

5

状況を考えると、XML ファイルを使用してあなたが取っているデータ駆動型のアプローチは良いもののように思えます。しかし、なぜエラー コードがまったく変化しているのか疑問に思います。これは、開発中のライブラリに対して適切な設計が行われていないことを示唆しています。エラー コードの解釈を変更し続ける必要はなく、エラー コードの構造が明確に定義されている必要があります。

全体的な「ライブラリ例外」例外クラスを作成し、ライブラリ エラーの「タイプ」に基づいて、スローするさまざまなタイプの例外ごとにサブクラス化することをお勧めします。少なくともそのようにして、特定のタイプの例外の 1 つがネットをすり抜けたとしても、すべてのライブラリ エラーをキャッチできます。すなわち。LibraryExceptionをキャッチしようとした後のようなものをキャッチしTerminalErrorExceptionます。

于 2013-01-31T11:13:36.590 に答える
3

状況に対する見方を少し変えると、この問題をより簡単に解決できると思います。

  1. あなたはフレームワークを扱っています。それを外部フレームワークと呼びましょう。
  2. 一方、フレームワーク - 内部フレームワークのラッパーを作成しています。
  3. コード (クライアント アプリケーション) は内部フレームワークを使用しており、それが問題のドメインに使用される機能を提供すると想定しています。私が理解しているように、そして私が信じているように、クライアントアプリケーションは外部フレームワークについて何も考えるべきではありません。

内部フレームワークの機能は明確に概説され、最終決定されていますか? それともそれも変化していますか?

変更されている場合 (おそらく外部フレームワークが原因)、内部フレームワークは開発中です。つまり、クライアント アプリケーションは、内部フレームワークが最初のバージョンの準備が整ったことをアナウンスする準備ができるまで (おそらく外部フレームワークが完了した後) 待機する必要があります。

エラー処理:

アプリケーションのエラーは契約のように機能します。関数の呼び出し元は、特定の例外的な状況、および特定の種類のエラーのみを想定しています。入力パラメーターや戻り値と同様に、考えられるエラーはそれぞれ関数ごとに事前定義され、文書化されています。

あなたにとっての意味:

  1. 内部フレームワークの最終設計を定義します (早ければ早いほど良い)。
  2. 内部フレームワークの各関数がスローできるエラーの種類を決定します。
  3. クライアント アプリケーションから内部フレームワークを使用し、予想される文書化された例外のみを想定します。内部フレームワークから予期されていないものを試したりキャッチしたりしないでください。基本的には契約に従います。
  4. エラー コードが変更されても、内部フレームワークの関数の概念は変更されません。以前にスローしたのと同じ種類のエラーをスローする必要があります (コントラクトに従って)。変更する必要がある唯一の部分は、新しいコードを予想される (縮小された) エラーの 1 つに変換する方法です。うまくいく方法で解決できます。

最後の仮定が正しいのはなぜですか? 内部アプリケーションの設計は最終的なものであり、変更されることはないと述べたからです。エラー コントラクトも最終設計の一部です。

例:

//external.
int Say(char* message);

//internal.
///<summary>
/// can throw (CONTRACT): WrongMessageException, SessionTimeOutException
void Say(string message) {
    int errorCode = External.Say(message);
    //translate error code to either WrongMessageException or to SessionTimeOutException.
}

翻訳できませんか?現在の契約エラーまたは外部フレームワークのいずれかで何か問題があります。おそらくプロセスを終了する必要がありますか? 何かがうまくいかなかった、予期しない!!!

//client.
...
try {
    Internal.Say("Hello");
}
catch (WrongMessageException wme) {
    //deal with wrong message situation.
}
catch (SessionTimeOutException stoe) {
    //deal with session timeout situation.
}

何か質問があれば教えてください。

エラー コードを例外に変換する:

これは明らかに、エラー コードごとにある種の分類です。カテゴリは各宛先例外にすることができ、例外は関数によって分類できます。これはまさにエラー コントラクトの意味です。関数ごとに例外を分類します。エラー コードを例外別に分類します。

以下は、このための疑似構成です。これを分類方法の最初のアイデアとして考えてください。

category Say [can throw]: { WrongMessageException, SessionTimeOutException }
category WrongMessageException [by error code]: { 100, 101 }
category SessionTimeOutException [by error code]: { 102, 103, 104 }

もちろん、そのような種類のインプレッション用のパーサーを作成する必要はありません (これは人間が読める疑似構成でした)。XML または任意の種類のソースを使用して同様の文を保存できます。これは、エラー変換ルールと関数コントラクトを構成するのに役立ちます。

参照

本: Jeffrey Richter - C# による CLR、第 3 版。第 20 章 - 例外と状態管理。サブチャプター - ガイドラインとベスト プラクティス。サブサブチャプター - 「契約」を維持するための実装の詳細の非表示。

この章では、例外をコントラクトとして説明し、関数によってスローされたコントラクトを分類する方法について説明します。これにより、ここで提供される説明の正確性と信頼性を確認できます。

于 2013-02-07T18:10:25.363 に答える
1

これはどうですか:

あなたはエラーカテゴリをいくつか保存したと言いました (DB または XML ファイル) は、私たちが ErrorCategory(Master) と ErrorDetail(Detail) と呼ばれるいくつかのマスター
詳細テーブル を楽しませて
くれます。アセンブリの完全な名前と指定された例外のクラス名を含むテキスト プロパティになります (例: CustomExceptions,CustomExceptions.TerminalError )すべてのカスタム例外の基本クラス 4が必要です。呼び出すことができますExceptionFactory クラスが必要です それを呼び出します ExceptionFactory には、次のような CreateException というメソッドがあります。
BaseCustomException calss
CustomExceptionFactory class

Public BaseCustomException CreateException(EceptinCategory category, ExceptionDetail detail)
{
   var customException = Activator.CreateInstance(category.CustomExceptionType) as      BaseCustomException;
   customException.SetDetails(detail);
   return customException;
}

そのため、実行時に CustomExceptionFactory オブジェクトは CustomExceptionType を使用して、Reflection を使用して特定の例外のインスタンスを作成します。
私は、CustomExceptionFactory と BaseCustomException をアセンブリに実装し、派生したすべての CustomExceptions を別のアセンブリに実装することを好みます。これにより、メイン アプリケーションは CustomExceptions.Dll とは無関係になります。将来的に
は、C++ ファクトリを変更することで、メイン アプリケーションを再構築する必要がなくなり、すべてのテーブルのデータの変更と CustomExceptions.Dll での実装が必要です。(XMLまたは構成ファイルを使用して同じソリューションを実装できます...)

これが役立つことを願っています。

于 2013-02-08T21:46:16.847 に答える
0

コードの指定を絶えず変更するよりも、古いコードを減価償却して指定を予約したままにしておく方がよいでしょう。作成者はデザインに興味がないようですので、stderr取得できるストリームで警告とエラーを報告してもらいます。

さらに、コードと文字列のペアを使用してCSVまたはXMLを作成するのは簡単なようで、アルゴリズムの作成者は適切と思われる場合は自由に編集できます。さまざまなタイプのエラー(入力エラーの場合は1000、端末エラーの場合は2000など)に対して特定の範囲のコード番号を予約し、ラッパーが作成したコードと文字列のペアを使用して戻りコードを解釈するようにします。

次に、数値範囲によって決定されるエラーのタイプに基づいて例外をスローします。

于 2013-02-05T20:39:13.790 に答える
0

柔軟でコードに依存したくない場合は、最初にアプリケーションを実行するときにリフレクションを使用してカスタム クラスを生成するのが最適だと思います。大雑把な説明はこちら。もしよろしければ、さらに説明できます。C++ コードのプロバイダーは、すべてのエラー コードを保持するクラスを作成する必要があります。たとえば、public class Errors{public static readonly IOError = 100} です。アプリケーションを起動すると、このクラスの変更を確認し、変更されている場合は、エラー コードごとに例外クラスを生成します。上記の例では、Exception .net クラスを継承するクラス IoException を生成します。その後、ラッパーで使用して、各例外を個別にキャッチできます。別の可能な解決策は、言及されているxmlを修正することです-エラーコードごとに例外クラスを追加します-エラーコード100の例を使用すると、IoExceptionクラスが作成されます。その後、このクラスを実装して使用する必要があります...

于 2013-02-02T20:29:06.953 に答える