ASP.NET MVC-ビジネスロジックはコントローラーに存在する必要がありますか?


97

Derik Whitaker が数日前に記事を投稿しましたが、これは私がしばらくの間興味を持っていたポイントです。ビジネスロジックはコントローラーに存在する必要があるのでしょうか。

これまでに見たすべてのASP.NET MVCデモでは、リポジトリへのアクセスとビジネスロジックをコントローラーに配置しました。中には検証を投げる人もいます。その結果、かなり大きなコントローラーが肥大化します。これは本当にMVCフレームワークを使用する方法ですか?これは、多くの重複したコードとロジックがさまざまなコントローラーに分散することになるだけのようです。


記事へのリンクは無効です-web.archive.org/web/20150906064521/http://devlicio.us/blogs/…は、興味のある他の人のためのarchive.orgからのコピーです。
スチュアートムーア

回答:


75

ビジネスロジックは実際にモデル内にある必要があります。あなたは太ったモデル、細いコントローラーを目指しているべきです。

たとえば、次のようにする代わりに:

public interface IOrderService{
    int CalculateTotal(Order order);
}

私はむしろ:

public class Order{
    int CalculateTotal(ITaxService service){...}        
}

これは、税が外部サービスによって計算されることを想定しており、外部サービスへのインターフェースについてモデルが知っている必要があります。

これにより、コントローラーは次のようになります。

public class OrdersController{
    public OrdersController(ITaxService taxService, IOrdersRepository ordersRepository){...}

    public void Show(int id){
        ViewData["OrderTotal"] = ordersRepository.LoadOrder(id).CalculateTotal(taxService);
    }
}

またはそのようなもの。


1
それでは、リポジトリの代わりにコントローラにサービスを注入しますか?その場合、作業単位の原則はどのように機能しますか?
Kevin Pang

もっと書きました。もっと理にかなっているといいのですが。以下もお読みください: weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model Railsに関するものですが、それでもまだ非常に適切です。
jonnii 2008年

私は個人的にリポジトリをサービスと呼びます。
Brad Wilson、

これらは間違いなく一種のサービスですが、特にデータアクセス用です。これは私が使用している規則にすぎず、特に私が主張するものではありません。
jonnii 2008年

1
これにより、モデルがITaxServiceと緊密に結合されます。別のプロジェクトまたは他のdllでモデルを再利用する場合は、ITaxServiceの実装または参照が必要です。そうしないと、モデルが破損し、SOLIDの原則に違反します。ITaxServiceにはモデルの参照が必要です。このようにして、ITaxService参照を必要とせずに、他のプロジェクトでモデルを再利用できます。
Mehmet Ali Sert、2016

65

Microsoft Patterns&Practicesの図が気に入っています。そして、「絵は千の言葉に値する」という格言を信じています。

図は、MVCおよびビジネスサービスレイヤーのアーキテクチャを示しています


6
それは本当に便利です!そのサイトのどこでこの図を見つけたか教えていただけますか?
ロブ教会

2
これは、Microsoftの「サーバー側の実装」msdn.microsoft.com/en-us/library/hh404093.aspxからのものです
Justin

わかりましたが、たとえばMVCアプリでは、ビジネスロジックはどこに行きますか?追加のサービスレイヤーまたは何かが必要ですか?
niico

14

これは興味深い質問です。

「ビジネスロジック」を完全にモデルに配置するという意味で、多数のサンプルMVCアプリケーションが実際にMVCパラダイムに準拠していないことは興味深いと思います。Martin Fowlerは、MVCはGang Of Fourの意味でのパターンではないと指摘しました。むしろ、プログラマーがおもちゃのアプリを超えて何かを作成する場合、パターン追加しなければならないというのはパラダイムです。

つまり、コントローラーにはビューとユーザーインタラクションを処理する追加の機能があり、1つの目的のみでオブジェクトを作成する必要があるため、「ビジネスロジック」はコントローラーに存在しないはずです。

より長い答えは、ロジックをコントローラーからモデルに移動する前に、モデルレイヤーの設計にいくつかの考慮を入れる必要があるということです。おそらくRESTを使用してすべてのアプリロジックを処理できます。その場合、モデルの設計はかなり明確なはずです。そうでない場合は、モデルが肥大化しないようにするために使用するアプローチを知っておく必要があります。


14

サービスレイヤーによる検証を示す、Stephen Waltherによるこの素晴らしいチュートリアルを確認できます。

検証ロジックをコントローラーアクションから別のサービスレイヤーに移動する方法を学びます。このチュートリアルでは、Stephen Waltherが、サービスレイヤーをコントローラーレイヤーから分離することで、懸念事項を明確に分離する方法を説明します。


2
これが最も正解です。私はさらに、サービスをコントローラーに公開しないで、代わりにMVVMパターンにあるようなViewModelコンセプトを使用することを選択することを提唱しています。デスクトップインターフェイス(たとえば、WindowsフォームまたはWPF)とWebインターフェイスを備えたビジネスアプリを作成するシナリオを想像してみてください。この問題を解決すると、ここでも推奨されている「細いコントローラー」のパターンが表示されます。結論:モデルやコントローラーにビジネスロジックを配置したり、コントローラーに不要なものを配置したりしないでください。
Sam

9

ビジネスロジックをコントローラーに含めることはできません。コントローラはできる限り細くする必要があり、理想的にはパターンに従ってください:

  1. ドメインエンティティを検索
  2. ドメインエンティティに作用する
  3. ビュー用のデータを準備する/結果を返す

さらに、コントローラーにはいくつかのアプリケーションロジックを含めることができます。

では、ビジネスロジックはどこに置くのでしょうか。モデル内。

モデルとは?さて、それは良い質問です。マイクロソフトのパターンと実践の記事をご覧ください(優れた検索については、AlejandroRのkudos)。ここには、モデルの3つのカテゴリがあります。

  • ビューモデル:これは単なるデータバッグであり、ビューとの間でデータを受け渡すための最小限のロジックがあり、基本的なフィールド検証が含まれています。
  • ドメインモデル:ビジネスロジックを備えたファットモデル。単一または複数のデータエンティティ(つまり、エンティティBでのアクションではなく、特定の状態のエンティティA)で動作します。
  • データモデル:ストレージ対応モデル。単一のエンティティ内に含まれるロジックは、そのエンティティにのみ関連します(つまり、フィールドaの場合、フィールドbの場合)。

もちろん、MVCはさまざまな種類のパラダイムです。ここで説明するのは、MVCが最上位層のみを占めることです。ウィキペディアでこの記事をご覧ください。

今日、MVCおよび同様のモデルビュープレゼンター(MVP)は、大規模システムのプレゼンテーション層にのみ適用される懸念の分離の設計パターンです。単純なシナリオでは、MVCはシステムの主要な設計を表す場合があり、データベースに直接到達します。ただし、ほとんどのシナリオでは、MVCのコントローラーとモデルは、サービスまたはデータレイヤー/層に緩やかに依存しています。これはすべてクライアントサーバーアーキテクチャに関するものです


-1

Dependency Injectorsを使用すると、ビジネスロジックがそれらに移動するため、きちんとしたクリーンなコントローラーが得られます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.