0

プログラム設計のガイダンスを探しています。

データベース内のデータを処理するクラス ライブラリがあります。ユーザーがデータを入力および管理するためのプレゼンテーション層である winforms アプリがあります。たとえば、ユーザーがデータを入力して保存しようとしたとします。winforms アプリから、次のようなことを行います。

MyTool theTool = new MyTool();
MyTool.FirstName = this.Textbox1.Text;
MyTool.LastName = this.Textbox2.Text;
//etc...
int result = MyTool.SaveData(); //result is the ID of the inserted record.

MyTool は、クラス ライブラリの型です。このタイプ内では、次のようになります。

public int SaveData()
{
   if (IsReadyForInput())
   {
   //..open a DB connection and save out the data
   //..get the ID of the saved record
   }
   else
   {
      throw new ArgumentException("One or more arguments prevented saving the data");
   }
   return theID
}

private bool IsReadyForInput()
{
   if (this.FirstName.Length == 0)
   { return false; }
   if (this.LastName.Length == 0)
   {return false;}
   return true;
}

今、私が興味を持っているのは、例外処理がどのように機能するかについての最良の設計です。たとえば、上記の方法はまったく具体的ではないため、ユーザーは何が問題なのかわかりません。したがって、これを次のように書き直すことができます。

public void SaveData()
{
   string errMess = IsReadyForInput();
   if (errMess.Length == 0)
   {
      //..open a DB connection and save out the data
      //..get the ID of the saved record
   }
   else {
      throw new ArgumentException(errMess);
   }
   return theID
}

private string IsReadyForInput()
{
   if (this.FirstName.Length == 0)
   { return "Specify a first name"; }
   if (this.LastName.Length == 0)
   {return "Specify a last name";}
   return true;
}

ただし、文字列の長さを比較してエラー メッセージを見つける方法は、非常に洗練された (または高速な) 方法とは思えません。私は次のようなものを書いてみました:

public void SaveData()
{
   ValidateInput();
   //..open a DB connection and save out the data
   return theID
}

private void ValidateInput()
{
   if (this.FirstName.Length == 0)
   { throw new ArgumentException("Specify a first name"; }
   if (this.LastName.Length == 0)
   {throw new ArgumentException("Specify a first name"; }
}

これに関する問題は、フロントエンドが「SaveData」を呼び出しているときに実際に ValidateInput によって例外がスローされることです。そのため、例外が一番上に到達すると、私にはあまり明確ではないように見えます (特に「ValidateInput を呼び出す方法が複数ある場合)」 ()" MyTool 内から)。

さらに、エラーがスローされた場合、ID が返されないため、フロント エンドで例外を処理する最善の方法が何であるかはわかりません。

この状況と一般的な検証/エラー処理を処理する方法についてのガイダンスを探しているだけだと思います。助けてくれてありがとう。

4

2 に答える 2

1

私が最初に疑問に思うのは、通常の制御フローで十分な場合に、例外をスローする必要があるかどうかです。

if (IsReadyForInput())
{
    //..open a DB connection and save out the data
    //..get the ID of the saved record
}
else 
{
    //..do whatever you need in case of invalid input
}

この提案の明らかな問題は、クラス ライブラリのどこかにメソッドがあり、必要な効果 (ユーザーへの警告の表示など) の一部が WinForms レイヤーで発生することです。ただし、これはより良い解決策を示唆しています。つまり、WinForms コードで検証を行うには:

if (IsReadyForInput())
{
    int result = theTool.SaveData();
    //...and whatever else should happen.
}
else
{
    //..do whatever you need in case of invalid input
}

上記のアプローチは、たとえば、例外をスローしたり、失敗を通知するために特別な戻り値を使用したりする場合と比較して、より単純であり、プログラムの各部分の相互依存が少なくなります (MyToolユーザー入力の検証を気にする必要がないため)。

于 2013-11-01T03:07:26.297 に答える
0

FluentValidation ( http://fluentvalidation.codeplex.com/ ) をご覧ください。私はそれがあなたが探しているものだと思います。

それを使用して、検証ルールを定義し、その検証メソッドを呼び出すことができます。コードで例外がスローされることなく、潜在的な検証エラーの完全なリストが返されます。

于 2013-11-01T02:49:07.647 に答える