テーブルの値をエンドユーザーに表示するドロップダウンリストがあります。これらの値をアルファベット順に並べ替えたいのですが。
適切なMVC設計によると、モデル、ビュー、コントローラーのどのレイヤーにソートロジックを配置すればよいですか?
編集:LarsHの質問「どの並べ替え順序が必要かを決定するコードを意味しますか?または、並べ替えを実行するコードを意味しますか?」に対して、私は元々、どの並べ替え順序が必要かを決定するコードを参照していました。
テーブルの値をエンドユーザーに表示するドロップダウンリストがあります。これらの値をアルファベット順に並べ替えたいのですが。
適切なMVC設計によると、モデル、ビュー、コントローラーのどのレイヤーにソートロジックを配置すればよいですか?
編集:LarsHの質問「どの並べ替え順序が必要かを決定するコードを意味しますか?または、並べ替えを実行するコードを意味しますか?」に対して、私は元々、どの並べ替え順序が必要かを決定するコードを参照していました。
回答:
(注:この引用と引用は@dasblinkenlightの回答から引用されていますが、私たちはそれを解釈することに同意しません。彼の投稿を読んで自分で決心してください)。
MVCの説明によると、
コントローラは、関連するビューにコマンドを送信して、モデルのビューの表示を変更できます(ドキュメントをスクロールするなど)。モデルにコマンドを送信して、モデルの状態を更新できます(ドキュメントの編集など)。
ビジネスルールと状態データが含まれているため、並べ替えロジック(並べ替えコンパレータ/並べ替えアルゴリズムなど)はモデルに属しています。モデルデータの並べ替え方法を変更すると、「モデルのビューの表示を変更する」カテゴリに完全に当てはまるため、コントローラは、model.changeSortedState()メソッドを呼び出して「並べ替えを行う」責任があります。
public void Sort(bool sortByDescending = false)
、falseの場合、昇順で並べ替えます。または、ロジックが非常に異なる場合は、2つの異なる並べ替え方法を用意します。
注文はモデルの一部なので、そこに行く必要があります。「すべてのデータ」をそのままプルすると、データは並べ替えられた順序で返され、並べ替え順序を選択するためのインターフェイスはありません。
ビューはコントローラーと相互作用するインターフェース(昇順/降順の矢印など)を提供し、モデルはデータを十分に理解して、要求されたデータのソートを実行します。ただし、(1)とは異なり、データの生のプルは必ずしもソートする必要はありません。
ビューは、ソートが行われていることを理解していません。その他に、選択されたソート方向を示す機能があります。そこにロジックを置かないでください。
並べ替え機能は、ある状況下では純粋にビューで使用できます(私は手に負えないと考えることができます。それ以外にもあります)。
すべてのデータが既にビューにあり、ドメインの知識を使用してソートを実行する必要がない「ダム」ソート。たとえば、非常に単純な文字列または数値の比較。これは、たとえば、結果が複数のページに分割される可能性が高いWebページの検索結果では不可能です。
MVCの説明によると、
コントローラは、関連するビューにコマンドを送信して、モデルのビューの表示を変更できます(ドキュメントをスクロールするなど)。モデルにコマンドを送信して、モデルの状態を更新できます(ドキュメントの編集など)。
これによると、モデルデータの並べ替え方法を変更すると、「モデルのビューのプレゼンテーションを変更する」カテゴリに完全に分類されるため、並べ替えロジックはコントローラーに属します。
編集:コメントで発声された複数の誤解を明確にするために、「ソートロジック」はソートを実行するコードではありません。ソートを定義するのはコードです。並べ替えロジックは、個々のアイテムを互いに比較して順序を確立する(例:のインスタンスを介してIComparator<T>
)、または外部システムによる順序付けに使用するオブジェクトを構築するロジックを含む(例:そのインスタンスを介して)。並べ替えコードは、ビュー内、モデル内、またはモデル(SQLデータベースなど)を支える永続化レイヤー内でも。IOrderedQueryable<T>
)。このロジックはアプリケーションの「ビジネス」側に関連する知識を必要とするため、コントローラーに属しています。並べ替えを実行するだけで十分ですが、実際に実行するコードとは別です
IComparer<T>
。モデルからのデータの取得を含む、ソートの残りの「ボイラープレートメカニックス」はビュー次第です。
{Unknown, Pass, Fail}
。さらにUnknown
、ユーザーが選択した昇順または降順に関係なく、常に最後にソートする必要があると仮定します。このロジックをビューに配置すると、code
フィールド内のデータのビジネス特性についてビューに多くのことがわかります。ビューはそれを認識すべきではありません。ユーザーが「ソート」ジェスチャーを実行したこと(たとえばヘッダーをクリックしたこと)のみが認識します。残りはコントローラー次第です。
上記のどれでもない。並べ替えはビジネスロジックであり、ビジネスロジックは3つのいずれにも属しません。アプリケーションのすべてのコードがモデル、ビュー、またはコントローラーになるわけではありません。
私がMVCアプリで一般的に行うことは、すべてのビジネスロジックを実行するサービスレイヤーがあることです。サービス層のメソッドには、適切に名前が付けられたパラメーターを持つ、クリーンでシンプルなAPIが必要です。次に、これらのメソッドをコントローラーから呼び出して、モデル内のデータを操作できます。
その意味では、並べ替えは「コントローラー内」ですが、並べ替えを行うコード自体はコントローラーに実装するのではなく、コントローラーから呼び出す必要があります。
明らかにコントローラではありません:ビューとモデルにメッセージを送信しますが、できる限り少ない作業を行う必要があります。ユーザーがソートを変更できる場合、モデルまたはビューにそれを通知することにより、コントローラーによって要求が処理されます。
それが純粋なビューのものであれば、ビューかもしれません。アプリケーションがソートなしでも同様に機能する場合、ソートは表現の一部にすぎず、ビューに表示されます。
順序付けがドメインの固有の部分である場合、それはモデルに入れる必要があります。
したがって、選択は-これはドメインビジネスロジックまたはプレゼンテーションロジックの一部であると思いますか。
適切なMVC Model2または従来のMVCパターンを実装している場合、モデルレイヤーによって提供されるデータの順序付けは、モデルレイヤーへのビューの要求によってトリガーされる必要があると言えます。ビューは順序付けられたデータを要求し、モデルレイヤーはそれを提供します。
ただし、ASP.NET MVCのMVCパターンの解釈を使用しているため、標準のMVCとは少し異なります。ViewModelインスタンスは、モデルレイヤーからの順序付けされた情報を要求する必要があります(何らかの理由で、ASP.NETフレームワークはテンプレートを呼び出す必要があると考えています「ビュー」とビューは「ビューモデル」と呼ばれるべきです..それは奇妙です)。
私は通常、他の回答と同様に、パターンに沿った状態を保つためにコントローラーでそれを行います。理由については、以下を参照してください。
私はこれを熟考し、答えと関連資料を読んでいます、そして実際的に言えば、それはあなたのアプリケーションに依存するだろうと私は言うでしょう:
中規模/大規模のアプリケーションであるか、複数のUIが関連付けられているか(Windowsアプリ、Webインターフェイス、電話インターフェイスなど)。
明確に定義された単一のUI Webサイトで、EF Code Firstのようなものを使用していて、サービスレイヤーを作成する予定がない、または意図していない場合、簡単な拡張メソッドを使用してそれを実現する予定です。
上記と同じである場合、BUTをそのままの拡張メソッドで実装することはできません。
総括する:
独断的な答え:サービス層
実用的な答え:通常はコントローラー
原則として、ソートはビジネスロジックであるという考えに同意しますが、それを元に分解すると、「クライアントは製品ページに日付でソートされた画像を表示したい」というような結果になるため、次のことが明らかになります。データの並べ替え順序は通常、任意ではありません。たとえ並べ替えがなくても、それは省略によるビジネス上の決定であるためです(空のリストは引き続きリストです)。
しかし、これらの回答は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から。
私はこの質問に正解があるとは思いません。可能な場合は複雑なビジネスロジックを抽象化する必要がありますが、車輪の再発明を犠牲にする必要はありません。
myList.OrderBy(x => x.CreationDate)
-これを行うためだけに、不要な追加レイヤーを導入する必要は実際にはありません。これに追加して、ページングされソートされたデータが必要な場合はどうしますか?テーブル全体をクエリし、並べ替えて、必要なものを保持しますか?呼び出すだけmyList.OrderBy(x => x.Date).Skip((page-1)*pageSize).Take(pageSize)
で、不要なデータは取得されません。
MVC Webサイト、WebForms Webサイト、およびモバイルアプリケーションがあるとします。
これらのプレゼンテーションレイヤー間で並べ替えを一貫させる場合は、プレゼンテーションレイヤーの外側で並べ替えを行います。サービスは良い候補です。
それ以外の場合は、そのロジックをビューモデルに格納します。どうして?再利用可能で、簡単にテストできるからです。
あなたがリストした3つのうち、それはコントローラーに属していると私は言うでしょう。ただし、この種のロジックをコントローラーに配置することはあまり好きではありません。私は通常、コントローラーが通信するサービス層を作成します。サービス層は、データストアとの通信と並べ替えロジックの処理を担当します。小さなアプリケーションの場合は、コントローラに座っても問題ありません。
これはasp.netを念頭に置いて尋ねられた質問ですが、誰かがRailsについて言及しているので、そのコンテキストで問題を検討することは興味深いと思いました。Railsでは、フレームワークとActiveRecord / ActiveQuery apiがプロビジョニングするため、コントローラーアクションとして取得と並べ替えを実行することは自然であり、かなり一般的です。一方で、静的な項目に対して何らかのカスタムの並べ替え順序を定義し、それをモデルに入れてコントローラーが使用できるようにすることで、モデルが実行しなくても、並べ替えロジックで役割を果たすことができます。直接操作します。それが何であれ、ビューにソートロジックを配置することは一般的に嫌われます。
いくつかの回答がコントローラーまたはモデルのいずれかにソートを置くことに絶対的に反対していることを少し面白がっており、それらは私の好みにはあまりにも面白すぎると思いますが、使用されるフレームワークの性質と関連する通常の規則に依存すると思いますそれ。私はまた、分離を最初に持つことがより重要であるというビルKのコメントにも同意します。