0

私は、複数のプレゼンテーションレイヤーを持つことができるWebアプリケーションを開発するように依頼されました。現在はWeb上にありますが、間もなくデスクトップやその他のプラットフォーム上に配置される予定です。それで、私はそれを最もよくする方法を探し回った。階層化されたアプローチを使用する方がよいことがわかりました。

さまざまなPLからアクセスできるWebサービスとしてBLLを使用することを考えています。BLLは、データ固有の操作のためにDALにアクセスします。これまでのところ良いですが、WebアプリにASP.NETMVCを使用することを考えていました。「コントローラー」には基本的にビジネスロジックが含まれているため、少し混乱しています。それは良い選択肢ですか?MVCと上記のレイヤーを使用して同じパスをたどると、コントローラーにBLLが含まれるとは限りませんが、ダミーになります。

それは正しい方法ですか?

4

1 に答える 1

3

推奨されるレイヤーは次のとおりです。

  • プレゼンテーション (MVC、WPF、Whatever): プレゼンテーション ロジックのみが含まれます (ビジネス ロジックは含まれません)。コントローラーはアプリケーション/サービス レイヤーとの通信のみを処理し、通信を調整します。

  • 分散サービス (リモート ファサード): 多くのクライアントがあり、その一部は Windows アプリであり、他は Web アプリであるため、ビジネス レイヤーをコンシューマーに公開するリモート サービス レイヤー (WCF サービスまたは Web サービス) を作成することをお勧めします (送信および受信 DTO が望ましい)。

  • アプリケーション層: ドメイン層との通信を処理し、トランザクション ロジックと技術サービスを調整する層。DTO を使用している場合は、ドメイン オブジェクトを DTO に、またはその逆に変換します。

  • ドメイン層: エンティティと値オブジェクトを含みます。これは、データとロジックをカプセル化するオブジェクト指向のドメイン オブジェクトに関して設計されたビジネス ロジックの中核です。リポジトリ パターンを使用している場合は、リポジトリ インターフェイスを含めることもできます。単一のエンティティに収まらないロジックのドメイン サービス。

  • データ アクセス: NHibernate や EF などの ORM などのデータ アクセス手法を使用して、エンティティをデータベース テーブルにマップします。

  • インフラストラクチャ / 共通: インフラストラクチャ コードとロギングなどの分野横断的な技術サービス

各レイヤーについて小さな例を挙げようと思います: 不完全な仮説の例では、発注書を有効にしたいとします。

プレゼンテーション層 (MVC):

public class PurchaseOrderController
{
  public ActionResult ActivateOrder(int id)
  {
    var response = _orderManagementService.ActivateOrder(id); // Call distributed service (Web Service)

    if(response.Succeed)
      return new SuccessActionResult();
    else
      return new FailedActionResult(response.Reason);
  }
}

分散サービス層 (Web サービス):

public class OrderManagementWebService : IOrderManagementService
{
  private readonly IOrderExecutionService _orderService;

  public OrderManagementWebService(IOrderExecutionService orderService)
  {
    _orderService = orderService; // Order Service from application service
  }

  public ActivationResult ActivateOrder(int id)
  {
    var response = _orderService.ActivateOrder(id); // Call the application layer to execute the logic
    if(
  }
}

アプリケーション層:

public class OrderExecutionService : IOrderExecutionService
{
  private IOrderRepository _orderRepository;

  public OrderExecutionService(IOrderRepository orderRepository)
  {
    _orderRepository = orderRepository;
  }

  public ActivationResult ActivateOrder(int id)
  {
    var order = _orderRepository.GetById(id); // Get the order from repository

    try
    {
      order.Activate(); // Call business logic inside the order entity
      return new ActivationResult { Success = true } ;
    }
    catch(ActivationException ex)
    {
      LogFactory.GetLog().Exception(ex); // Call log from infrastructure layer
      return new ActivationResult { Success = false, Reason = ex.Message } ;
    }
  }
}

ドメイン層:

public class PurchaseOrder : Entity
{
  // Properties and fields (Data)
  public int Id { get; private set; }
  public Customer Customer { get; private set; }

  // Methods (contains business logic)
  public void Activate()
  {
     if(Customer.IsBlacklisted)
       throw new InvalidCustomerException(...);

     if(_lineItems.Count == 0)
       throw new NoItemsException(...);

     this.SetStatus(OrderStatus.Active);

     .....
  }
}

リポジトリ (データ アクセス層):

public class OrderRepository : IOrderRepository
{
  public PurchaseOrder GetById(int id)
  {
    // data access code to access ORM or any data access framework.
  }
}

インフラ:

public class Logger : ILogger
{
  public void Exception(Exception ex)
  {
   // write exception to whatever
  }
}
于 2011-10-19T12:03:28.853 に答える