データベースの初期化呼び出しをC#コンストラクターに入れても大丈夫ですか? [閉まっている]
-
03-07-2019 - |
質問
これはさまざまなコードベースを見てきましたが、これが一般的に眉をひそめるかどうかを知りたいと思いました。
例:
public class MyClass
{
public int Id;
public MyClass()
{
Id = new Database().GetIdFor(typeof(MyClass));
}
}
解決
これが一般に良い設計とは見なされないいくつかの理由があります。そのうちのいくつかは、難しいユニットテストを引き起こしたり、エラー処理の難しさをすでに述べています。
私がそうしないことを選択する主な理由は、オブジェクトとデータアクセスレイヤーが非常に密に結合されているためです。例として、インスタンスに値を割り当てずにそのオブジェクトを使用して、そのクラスの新しいインスタンスを永続化する必要があるインスタンスに遭遇した場合はどうなりますか?コンストラクタをオーバーロードしてから、他のすべてのロジックがこの新しいケースを処理することを確認するか、継承してオーバーライドする必要があります。
オブジェクトとデータアクセスが分離されている場合、インスタンスを作成してからハイドレートしないことができます。または、同じエンティティを使用し、異なる永続レイヤーを使用する別のプロジェクトがある場合、オブジェクトは再利用可能です。
過去にプロジェクトで結合の簡単なパスを取っていると言った:)
他のヒント
まあ..しません。ただし、この場合も、通常、クラスは独自のデータを取得する責任を負いません。
クラスにdbクラスのMock / Stubバージョンを強制的に使用させることができないため、クラスの単体テストを記述することも難しくなります。こちらをご覧ください: http://en.wikipedia.org/wiki/Dependency_injection
DB接続を参照する場合は、使い捨てパターンを使用できます。
public class MyClass : IDisposable
{
private Database db;
private int? _id;
public MyClass()
{
db = new Database();
}
public int Id
{
get
{
if (_id == null) _id = db.GetIdFor(typeof(MyClass));
return _id.Value;
}
}
public void Dispose()
{
db.Close();
}
}
使用法:
using (var x = new MyClass())
{
/* ... */
} //closes DB by calling IDisposable.Dispose() when going out of "using" scope
はい、できますが、それは最良の設計ではなく、コンストラクターでのエラー処理は他の場所ほど整頓されていません。
このアプローチで考えられる唯一の問題は、DB初期化のエラーがコンストラクターからの例外として伝播されることです。
なぜ本物の代わりにモックオブジェクト/スタブを使用したいのですか? 自動車メーカーが板紙モデルを使用することに同意しますか クラッシュテスト用ですか?