並べ替えロジックは、モデル、ビュー、またはコントローラーのいずれに配置する必要がありますか?[閉まっている]


157

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

適切なMVC設計によると、モデル、ビュー、コントローラーのどのレイヤーにソートロジックを配置すればよいですか?

編集:LarsHの質問「どの並べ替え順序が必要かを決定するコードを意味しますか?または、並べ替えを実行するコードを意味しますか?」に対して、私は元々、どの並べ替え順序が必要かを決定するコードを参照していました。


6
コメントの不一致を解決するために、「ソートロジック」で何を意味するかを言うと役立つでしょう。どのソート順が必要かを決定するコードを意味しますか?またはソートを実行するコード?
LarsH

9
MVCのデザインは特別なものでも魔法のようなものでもありません。これは、単なる出発点にすぎません。ニーズに合わせて、いつでもリファクタリングできることを忘れないでください。さまざまなベンダーがツールキットのニーズに基づいてコントローラーまたはビューに入る内容を再定義するため、合意を見つけるのが難しいことに気づきました。重要なことは、モデルをビュー/コントローラーから分離することです。また、MVPパターンからより多くのマイレージを得る可能性があります。これは、まさにこの領域でより具体的だと思います。
ビルK

9
多分これはプログラマに移行する必要があります。
Alfredo Osorio 2012

57
間違いなくコントローラで。それかモデルのどちらかです。またはビュー。
mob

2
絶対に決して、決して、決して、決して、これまでにない。
contactmatt 2012

回答:


49

(注:この引用と引用は@dasblinkenlightの回答から引用されていますが、私たちはそれを解釈することに同意しません。彼の投稿を読んで自分で決心してください)。

MVCの説明によると、

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

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


8
同じデータを2つの異なるビューに表示し、異なる方法で並べ替える場合はどうなりますか?
s4y

これも、model.SortAscending()およびmodel.SortDescending()と同じ方法で実行し、コントローラーから呼び出す必要があります。
ブリジ2012

1
@Brij適切なMVCでは、2つのビューが同じモデルを共有できませんか?
KOVIKO、2012

@Sidnicious異なるパラメーターを取る1つの並べ替え方法を使用することが理にかなっている場合。たとえばpublic void Sort(bool sortByDescending = false)、falseの場合、昇順で並べ替えます。または、ロジックが非常に異なる場合は、2つの異なる並べ替え方法を用意します。
MattMcGowan 2015年

@Sidniciousには、ソートロジック以外のすべてを単一の3番目のモデルに委任する2つの異なるモデルがあります。docs.google.com/drawings/d/...
rightfold

62

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

単純なMVC図ウィキペディアより

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

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

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

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

どちらの場合にも、

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

小さな警告

並べ替え機能、ある状況下では純粋にビューで使用できます(私は手に負えないと考えることができます。それ以外にもあります)。

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


58
ビューはユーザーを見ることができます!?
ファルツァー2012

41
モデルがビューを更新します!?
だます

13
ウィキペディアの記事はうんざりです:「コンポーネントの相互作用」セクションは、右側に示されている図(ここに投稿したばかり)と競合しています。次に、モデルはビューを「更新」しません。状態が変化したときにビューに通知します。ビューは更新方法を決定します。ああ。不明瞭な情報がたくさんあるのに、なぜこの質問には1000の異なる答えがあるのでしょうか。
KyleM

4
@cHao確かに。ウィキペディアのグラフはかなり変だと思いますか?:)
だます

6
@StephenSarcsamKamenarと他の全員:いいえ、画像は完全に理にかなっています。これは、コード接続ではなく、データ流れを示しています。
イズカタ

18

MVCの説明によると、

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

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

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


12
-1どのように管理して、この見積もりからこれを結論付けましたか?コントローラがモデルから情報を取得することになっているとどこかで言われましたか?コントローラーは、状態を変更するコマンドを送信します。情報の抽出や操作については何も言われていません。
tereško

3
@tereškoコントローラーがモデルから情報を取得する必要があるという私の回答から、どうやって結論を下すことができましたか?「ソートロジック」とは、順序を確立するために必要なロジックのみを意味します。C#の用語では、の実装を提供しますIComparer<T>。モデルからのデータの取得を含む、ソートの残りの「ボイラープレートメカニックス」はビュー次第です。
dasblinkenlight 2012

3
"..ソートロジックはコントローラーに属します.."、これは他に何を意味しますか?
tereško

3
「コントローラは、関連付けられたビューにコマンドを送信して、ビューのプレゼンテーションを変更できます」というのは、コントローラからのコマンドに応じて、ビューがソートを行うように聞こえます。
サミュエルエドウィンワード

1
@KyleMただし、ビューには常にソートロジックを含めるのに十分な知識がありません。たとえば、列挙型の1つに対応する数値コードを持つフィールドを考えてみます{Unknown, Pass, Fail}。さらにUnknown、ユーザーが選択した昇順または降順に関係なく、常に最後にソートする必要があると仮定します。このロジックをビューに配置すると、codeフィールド内のデータのビジネス特性についてビューに多くのことがわかります。ビューはそれを認識すべきではありません。ユーザーが「ソート」ジェスチャーを実行したこと(たとえばヘッダーをクリックしたこと)のみが認識します。残りはコントローラー次第です。
dasblinkenlight 2012

10

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

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

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


5
最近、「サービスレイヤー」(ビジネスロジック)をモデルの一部と見なしている人がいることを知りました。
Marvo 2012

@Marvo特定のロジックの一部がデータ型に密接に関連付けられているため、それらを1つのクラスにカプセル化することが理にかなっている場合があると思います。(たとえば、時刻と日付の関数)。ただし、一般的には、モデルオブジェクトがデータを保持するだけの場合に最も効果的に機能します。
15:03

では、ビジネスロジックはMVCパターンのどこに「生きている」のでしょうか。
Marvo、2012

2
アプリケーションがMVCパターンを使用するからといって、アプリケーション内のすべてのコードがモデル、ビュー、またはコントローラーになるわけではありません。それは文字通りデザインパターンをとっています。たとえば、アプリケーションにはおそらく何らかの構成ファイルがあります。この構成ファイルは、ユーザーデータのモデル化、ビューの表示、モデルを介したビューへのデータフローの制御を行いません。その設定ファイルは、独自の種類のものです。
2012

モデルの構成ファイルの一部と同じくらい簡単に考えることができます。モデルはデータベースである必要はありません。私はあなたが正しいか間違っていると言っているのではありません。私が最近行ったように(私はあなたが持っているのと同じ見解を持っているので)あなたに少し主題をググって他の人が言っていることを見てあなたに提案するだけです。
Marvo 2012

8

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

それが純粋なビューのものであれば、ビューかもしれません。アプリケーションがソートなしでも同様に機能する場合、ソートは表現の一部にすぎず、ビューに表示されます。

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


「コンパレータまたはソート記述子を提供する」ことは「作業を行う」と見なされますか?並べ替えロジックがコンパレーターまたは並べ替え記述子にカプセル化されているため、「並べ替え作業」がsortメソッドまたはモデルのバックエンドで行われたとしても。
dasblinkenlight 2012

あなたが提供することによって何を意味するかに依存します:渡しても大丈夫です。ただし、コンパレータは、コントローラではなく、モデルまたはビューの一部である必要があります。
Jens Schauder、2012

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

したがって、選択は-これはドメインビジネスロジックまたはプレゼンテーションロジックの一部であると思いますか。

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

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


12
あなたは、「ソートロジック」によって彼らが何を意味するかについてのあなた自身の仮定を適用して、複数の回答に反対票を投じました。あなたの仮定はまったく正しくありません-ソートロジックには検索が含まれていません。
dasblinkenlight 2012

1
@dasblinkenlight、はい、コントローラーが並べ替えを実行する必要があることをすべて示唆しているため、複数のトピックに反対票を投じます。これは間違いです。そして..人々..同意しないという理由だけで、私のコメントへのフラグ付けをやめてください。
テレシュコ

明確にするために:私はあなたの回答が間違っていないのであなたの回答に反対票を投じませんでした。正直なところ、あなたの回答がどのようにして多くの反対票を獲得できたのかはわかりません。
dasblinkenlight 2012

@dasblinkenlight naah ..私はこのトピックでたまたま消えてしまった私のコメントについて怒っていました。
tereško

5

私は通常、他の回答と同様に、パターンに沿った状態を保つためにコントローラーでそれを行います。理由については、以下を参照してください。

私はこれを熟考し、答えと関連資料を読んでいます、そして実際的に言えば、それはあなたのアプリケーションに依存するだろうと私は言うでしょう:

中規模/大規模のアプリケーションであるか、複数のUIが関連付けられているか(Windowsアプリ、Webインターフェイス、電話インターフェイスなど)。

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

明確に定義された単一のUI Webサイトで、EF Code Firstのようなものを使用していて、サービスレイヤーを作成する予定がない、または意図していない場合、簡単な拡張メソッドを使用してそれを実現する予定です。

  • この場合、私はそれを実用的には時間/予算に関して最適なものとしてコントローラーに配置します。

上記と同じである場合、BUTをそのままの拡張メソッドで実装することはできません。

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

総括する:

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

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


「ビューのデータの準備」を担当する定義コントローラーはどれですか。
tereško

1
@tereško:バリエーションセクションのmsdn.microsoft.com/en-us/library/ff649643.aspxで説明されているように、モデルは "パッシブ" です。「HTTPはこの例です」を参照してください。純粋主義者はこれに異議を唱えるかもしれませんが、MALから始めてコントローラーで直接EFまたは他のモデルを使用している可能性があり、BALを介さずにそれをこのように考えると、パターンをさらに理解するための障壁を下げることが容易になります。
ルークボーン

1
あなたが話しているのは「貧血モデル」です。
tereško

ポイントが指摘したように、あなたの提案に従って問題のある説明を削除しました。入力のための乾杯!
ルークボーン

3

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

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


2

原則として、ソートはビジネスロジックであるという考えに同意しますが、それを元に分解すると、「クライアントは製品ページに日付でソートされた画像を表示したい」というような結果になるため、次のことが明らかになります。データの並べ替え順序は通常、任意ではありません。たとえ並べ替えがなくても、それは省略によるビジネス上の決定であるためです(空のリストは引き続きリストです)。

しかし、これらの回答はORMテクノロジーの進歩を考慮していないようです。私はエンティティフレームワークに関してのみ話すことができます(これが真の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から。

私はこの質問に正解があるとは思いません。可能な場合は複雑なビジネスロジックを抽象化する必要がありますが、車輪の再発明を犠牲にする必要はありません。


私は同じことを考えていました、ここでの答えはORMと拡張メソッドを考慮に入れていないようです。ほとんどの場合、並べ替えロジックは同じくらい簡単ですmyList.OrderBy(x => x.CreationDate)-これを行うためだけに、不要な追加レイヤーを導入する必要は実際にはありません。これに追加して、ページングされソートされたデータが必要な場合はどうしますか?テーブル全体をクエリし、並べ替えて、必要なものを保持しますか?呼び出すだけmyList.OrderBy(x => x.Date).Skip((page-1)*pageSize).Take(pageSize)で、不要なデータは取得されません。
バラージュ

1

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

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

それ以外の場合は、そのロジックをビューモデルに格納します。どうして?再利用可能で、簡単にテストできるからです。


0

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


2
それはモデル側により多くのロジックを置くでしょう、そうですか?
ライアンコーン

ええ、「サービス層」についての私の理解は、それがモデルの一部であるということです。
Marvo 2012

0

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

いくつかの回答がコントローラーまたはモデルのいずれかにソートを置くことに絶対的に反対していることを少し面白がっており、それらは私の好みにはあまりにも面白すぎると思いますが、使用されるフレームワークの性質と関連する通常の規則に依存すると思いますそれ。私はまた、分離を最初に持つことがより重要であるというビルKのコメントにも同意します。

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