web-dev-qa-db-ja.com

モデル、ビュー、またはコントローラーにソートロジックを配置する必要がありますか?

テーブルの値をエンドユーザーに表示するドロップダウンリストがあります。これらの値をアルファベット順にソートしたいと思います。

適切なMVC設計によれば、モデル、ビュー、コントローラーのいずれのレイヤーに並べ替えロジックを配置する必要がありますか?

[〜#〜] edit [〜#〜]:LarsHの質問「あなたはどのソート順が望ましいかを決定するコードを意味しますか?またはソートを実行するコードを意味しますか?」必要なソート順を決定するコードを参照します。

156
Ryan Kohn

(注:この引用と引用は @ dasblinkenlight's answer から取られていますが、私たちはそれについての解釈に同意しません。彼の投稿を読んで、あなた自身の考えを決めてください)。

MVC description によると、

コントローラーは、関連するビューにコマンドを送信して、モデルのビューの表示を変更できます(たとえば、ドキュメントをスクロールすることにより)。モデルにコマンドを送信して、モデルの状態を更新できます(ドキュメントの編集など)。

モデルにはビジネスルールと状態データが含まれているため、ソートロジック(ソートコンパレータ/ソートアルゴリズムなど)はモデルに属します。モデルデータの並べ替え方法を変更すると、「モデルのビューの表示を変更する」カテゴリに分類されるため、コントローラーはmodel.changeSortedState()メソッドを呼び出して「並べ替えを行う」責任を負います。

47
KyleM

ソート順は誰が制御しますか?

Simple MVC diagram ( ウィキペディア から)

1)データ自体内の自然順序:

注文はモデルの一部であるため、そこに行く必要があります。 「すべてのデータ」の生のプルは、ソートされた順序でデータを返します。ソート順序を選択するインターフェースはありません。

2)ユーザーは、データの表示方法を制御する必要があります。

ビューは、コントローラーと対話するインターフェース(昇順/降順矢印など)を提供し、モデルはデータに対して要求されたソートを実行するのに十分なほどデータを理解します。ただし、(1)とは異なり、データの生のプルは必ずしもソートする必要はありません。

どちらの場合にも、

ビューは、並べ替えが行われていること、他の並べ替え方向が選択されていることを示す機能があることを理解していません。そこにロジックを入れないでください。

小さな注意点

ソート機能couldは、1つの状況(純粋に考えることができます。もっとあるかもしれません)の下で、純粋にビューに移動します。

すべてのデータがすでにビューにある「ダム」ソート。ソートを行うためにドメイン知識を使用する必要はありません。たとえば、非常に単純な文字列または数値の比較。たとえば、結果が複数のページに分割される可能性がある場合、Webページの検索結果ではこれは不可能です。

62
Izkata

MVC description によると、

コントローラーは、関連するビューにコマンドを送信して、モデルのビューの表示を変更できます(たとえば、ドキュメントをスクロールすることにより)。モデルにコマンドを送信して、モデルの状態を更新できます(ドキュメントの編集など)。

これによれば、モデルデータの並べ替え方法を変更すると、「モデルのビューの表示を変更する」カテゴリに分類されるため、並べ替えロジックはコントローラーに属します。

EDIT:コメントで表明された複数の誤解を明確にするために、「ソートロジック」はnotソートを実行するコード。ソートを定義するのコードです。ソートロジックは、個々のアイテムを相互に比較して順序を確立します(例:IComparator<T>)または、外部システムによる順序付けに使用されるオブジェクトを構築するロジックを含みます(例:IOrderedQueryable<T>)。このロジックは、アプリケーションの「ビジネス」側に関する知識を必要とするため、コントローラーに属します。ソートを実行するだけで十分ですが、実際に実行するコードとは別です。並べ替えるコードは、ビュー、モデル、またはモデルを支える永続レイヤー(たとえば、SQLデータベース)にある場合があります。

18
dasblinkenlight

上記のいずれでもありません。ソートはビジネスロジックであり、ビジネスロジックは3つのいずれにも属しません。アプリケーションのすべてのコードがモデル、ビュー、またはコントローラーになるわけではありません。

MVCアプリで通常行うことは、すべてのビジネスロジックを実行するサービスレイヤーがあることです。サービス層のメソッドには、適切な名前のパラメーターを持つクリーンでシンプルなAPIが必要です。その後、コントローラーからこれらのメソッドを呼び出して、モデル内のデータを操作できます。

その意味では、並べ替えは「コントローラー内」ですが、並べ替えを行うコード自体はコントローラーに実装されるべきではなく、コントローラーから呼び出されるだけです。

10
nont

明確にコントローラーではありません:ビューとモデルにメッセージを送信しますが、できる限り少ない作業を行う必要があります。ユーザーが並べ替えを変更できる場合、その要求はモデルまたはビューに通知することでコントローラーによって処理されます。

純粋なViewの場合はViewかもしれません。並べ替えを行わなくてもアプリケーションが同様に機能する場合、並べ替えは表示の一部にすぎず、ビューに表示されるはずです。

順序付けがドメイン固有の部分である場合、モデル内に配置する必要があります。

8
Jens Schauder
  • ビューは、プレゼンテーションロジックを含むことになっているMVCの一部です。
  • モデルレイヤーは、ビジネスロジックが含まれる場所です。
  • コントローラは、ユーザー入力に基づいて両方の状態のみを変更します。

選択肢は-これはドメインのビジネスロジックまたはプレゼンテーションロジックの一部だと思いますか。

適切なMVC Model2または従来のMVCパターンを実装している場合、モデルレイヤーによって提供されるデータの順序は、モデルレイヤーへのビューの要求によってトリガーされるべきだと言えます。ビューは順序付けられたデータを要求し、モデル層はそれを提供します。

ただし、ASP.NET MVCのMVCパターンの解釈を使用しているため、これは標準のMVCとは少し異なります-ViewModelインスタンスはモデルレイヤーから順序付けられた情報を要求する必要があります(何らかの理由で、ASP.NETフレームワークはテンプレートを呼び出す必要があると考えています) 「ビュー」とビューは「ビューモデル」と呼ばれるべきです..それは奇妙です)。

7
tereško

私は通常、コントローラーで他の回答に従ってパターンに沿ったままにします。理由については以下を参照してください。

私はこれを熟考し、答えと関連資料を読んでおり、実用的に言えば、例えばあなたのアプリケーションに依存すると言うでしょう:

中規模または大規模のアプリケーションであるか、複数のUIが関連付けられていますか(つまり、Windowsアプリ、Webインターフェイス、および電話インターフェイス)。

  • この場合、おそらくサービスレイヤーを構築してビジネスオブジェクトに配置し、コントローラーから適切なメソッドを呼び出します。

明確に定義された単一のUI Webサイトで、EF Code Firstのようなものを使用していて、サービスレイヤーを作成する意図がないか、まったく意図していない場合は、単純な拡張機能を使用してそれを達成することを計画しています:

  • この場合、時間/予算に関して実際的には最適であるとして、おそらくコントローラーに入れます。

上記のBUTと同じものが、そのままの拡張メソッドで実装できない場合。

  • ここではコントローラーよりも適切であるため、Modelクラスにポップすることを選択することもできます(その単一のタイプに本当に対応している場合)。並べ替えを複数のクラスに適用できる場合は、拡張メソッドで並べ替えてからコントローラーで呼び出します。

総括する:

独断的な答え:サービス層

実用的な答え:通常はコントローラー

5
bUKaneer

ドロップダウンリストで役立つほど十分に小さいテーブルデータからデータを並べ替えることをお勧めします。クエリによって既に並べ替えられているDBから取得する必要があります。私にとって、それはモデルをソートが適用される場所にします。

手作業でソートを行うことに決めた場合、モデルまたはコントローラーのいずれかをロジックの優先スポットとして使用することには良い議論があると思います。制限は特定のフレームワークになります。モデル内でのみデータを管理することを好みます。私はコントローラーを使用して、データ(モデル)とプレゼンテーション(ビュー)を結婚しました(自己)。

3
B0nk3r

私は原則としてソートがビジネスロジックであるという考えに同意しますが、それをOriginに分解すると、「クライアントは日付でソートされた画像で製品ページを表示したい」という結果になります。データの並べ替え順序は通常、arbitrary意的なものではありません。たとえ省略してもビジネス上の決定であるため、並べ替えが行われない場合でも(空のリストは依然としてリストです)。

しかし...これらの答えはORMテクノロジーの進歩を考慮していないようです。私はEntity Frameworkに関してのみ話すことができます(これが本当のORMであるかどうかについての議論を避けましょう、それはポイントではありません)それは私が使用するものですが、他のORMが同様の機能を提供していると確信しています。

MS MVCとEntity Frameworkを使用してProductクラスの厳密に型指定されたビューを作成し、ProductとImageテーブルの間に外部キー関係がある場合(FK_Product_Image_ProductIdなど)、すぐに並べ替えることができますビューで次のようなものを使用して表示中の画像:

@foreach(Image i in Model.Image.OrderBy(e => e.DisplayOrder)){ //etc etc... }

ビジネスロジックの80%を実行するために使用する特定のビジネスロジックレイヤーについて言及しましたが、すぐに使用できるものを模倣するビジネスロジックレイヤーに並べ替え機能を記述するつもりはありません。 Entity Frameworkから。

それを言う以外に、この質問に対する正しい答えはないと思います。可能な場合は複雑なビジネスロジックを抽象化する必要がありますが、車輪を再発明する費用はかかりません。

2
Rob

MVC Webサイト、WebForms Webサイト、モバイルアプリケーションがあるとします。

これらのプレゼンテーションレイヤー間で並べ替えを一貫させるには、プレゼンテーションレイヤーの外側で並べ替えを行います。サービスは良い候補です。

そうでなければ、そのロジックをビューモデルに格納します。なぜですか?再利用可能で簡単にテストできるためです。

1
user338195

あなたがリストした3つのうち、それはコントローラに属していると言えます。ただし、この種のロジックをコントローラーに配置することはあまり好きではありません。通常、コントローラーが通信するサービスレイヤーを作成します。このレイヤーは、データストアとの通信と並べ替えロジックの処理を担当します。ただし、小規模なアプリケーションの場合は、コントローラーに収まります。

0
Dismissile

これはasp.netを念頭に置いて質問される質問ですが、誰かがRailsに言及したので、そのコンテキストで問題を検討することは興味深いと思いました。 Railsでは、フレームワークとActiveRecord/ActiveQuery APIがプロビジョニングしているため、コントローラーアクションとしての取得とともに並べ替えを実行するのが自然で非常に一般的です。一方、静的アイテムのカスタム並べ替えの並べ替えを定義し、それをコントローラーで使用するモデルに配置して、モデルが実行されなくても並べ替えロジックで役割を果たすことができます操作を直接。それが何であれ、ビューにソートロジックを置くことは一般的に眉をひそめていると言っても安全です。

私は、いくつかの答えがコントローラまたはモデルのいずれかにソートを配置することに絶対に反対していることを少し面白がっています。それ。私はまた、そもそも分離を行うことがより重要であるというビルKのコメントに同意します。

0
prusswan