3層(階層ではなく、1台のマシンでプロジェクトを論理的に分離したいだけです)アーキテクチャを実装しようとしています。非常に多くの異なるアプローチを見つけたので、混乱しています。(もしあれば)最善の方法は何ですか?それはWinFormsアプリにあります。
今、私はプロジェクトに存在する必要がある3つのレイヤーについてのみ疑いを持っていません:
- UI (プレゼンテーション レイヤー)
- BLL (ビジネス ロジック層)
- DAL (データ アクセス層)
UIに、すべての WinForms を配置しました。オブジェクトにコントロールからのデータを入力し、それを BLL レイヤーに渡すためのロジックも必要です。
DALでは、次のように、ADO.NET を使用してデータ操作用のクラスとメソッドを配置したいと考えています。
public class OrderDAL
{
public OrderDAL()
{
}
public int Add(Order order)
{
//...add order to database
}
public int Update(Order order)
{
//...update order in database
}
//...etc.
}
問題は BLL にあり、レイヤー間でデータを渡すためにデータ転送オブジェクトを使用する必要がありますか、それともクラス全体を渡す必要がありますか?
DTOを使用する場合はOrder
、UI、BLL、および DAL を参照 する追加の共通クラスを作成する必要があります。
public class Order
{
public int Id { get; set; }
public DateTime Date { get; set; }
public string Number { get; set; }
public string CustomerName { get; set; }
public Order ()
{
}
}
ロジックを BLL に分割します。
public class OrderBLL
{
public OrderBLL()
{
}
public int Add(Order order)
{
OrderDAL orderDAL = new OrderDAL();
return orderDAL.Add(order);
}
public int Update(Order order)
{
OrderDAL orderDAL = new OrderDAL();
return orderDAL.Update(order);
}
//...etc.
}
このアプローチは、さまざまな名前で使用されますが、特に使用されます: hereまたはhere。
一方で、一部の「賢者」とその支持者 (ここのような) は、これを貧血ドメイン モデルと呼び、使用すべきではない悪い設計とアンチ パターンであると不満を漏らしています。
長所:
- DTO は設計上、データベース テーブルを簡単に表すことができます。
- 軽くて明確で、データベースに必要なフィールドのみが含まれています。
- DAL は BLL を参照する必要はありません。
短所:
- アンチパターン (怖いですね;P),
- OOP (メソッドから分離されたプロパティ) の違反、
- ロジックは異なるクラスにあるため、何かが変更されたときに維持するのがより困難になる場合があります。
したがって、反対のアプローチは、次のようにオブジェクト全体をレイヤー間で渡すことです。DTO はなく、BLL は次のようになります。
public class Order
{
public int Id { get; set; }
public DateTime Date { get; set; }
public string Number { get; set; }
public string CustomerName { get; set; }
public Order()
{
}
public int Add()
{
OrderDAL orderDAL = new OrderDAL();
return orderDAL.Add(this);
}
public int Update(Order order)
{
OrderDAL orderDAL = new OrderDAL();
return orderDAL.Update(order);
}
}
長所:
- これは、OOP ルールに従って、適切にカプセル化されたオブジェクトです (と思います ;))。
- ロジックとプロパティの両方が 1 か所にあるため、保守とデバッグが容易になります。
短所:
- オブジェクトを使用するには、DAL が BLL を参照する必要があります (これは、3 層レイヤーが行うべき方法ではありませんね)。
- クラスには、データベースで使用されていないフィールドが含まれている場合があり、データベースの一部のフィールド (Id など) は「実際の」オブジェクトを表していません。
だから、私が何を選んでも、いくつかのルールに違反するように見えます. では、どの方法を選択すればよいでしょうか。たぶん、私が見つけていない他のアプローチがありますか?