23

私はこれが初めてなので、我慢してください。私は最近、いくつかのプロジェクトで1つのMVCフレームワークを使用していますが、しばらくすると、MVCの「モデル」の有用性に幻滅します。

コントローラーとビューの有用性を理解しました。プレゼンテーションとロジックを分離することは、コードを将来的に保守しやすくするために重要ですが、必ずしも高速または堅牢である必要はありません。

そもそもすべてのロジックをコントローラー内に配置する必要がある場合、Model、特にActive-Recordの使用は見当たりません。私たちはすでにデータベースとの通信に非常に堅牢で使いやすい言語を持っています、私は正しいですか?これはSQLと呼ばれます。私にとって、モデルがアクティブレコードのように実装されている場合、その有用性は、アプリを複数のデータベースに適合させるかどうかによって異なります。

では、私が求めているのは、データベースを1つだけ使用している場合、なぜモデルとアクティブレコードを気にする必要があるのでしょうか。SQLだけを使用しないのはなぜですか?なぜ複雑さの余分な層?データベースクラスとSQL-awayを使用するよりも、モデルが実際にうまく機能するケーススタディ/実際のストーリーはありますか?

繰り返しになりますが、私があまりにも無知であるように思われる場合は申し訳ありませんが、モデルが重要である理由は本当にわかりません。回答ありがとうございます。

4

5 に答える 5

21

まず、SQLを抽象化するために、モデルレイヤーは必ず何らかのORMを使用すると想定しています。これは真実ではありません。Controllerレイヤーから緩く結合されているが、特定のDBMSに緊密に結合されているモデル層を作成できるため、フル機能のORMの使用は避けてください。

Hibernate(Java)、NHibernate(.NET)、Doctrine(PHP)、ActiveRecord-Rails(Ruby)など、実際のすべてのSQLステートメントを実際に生成できるORMライブラリがいくつかあります。ただし、ORMが不要であり、すべてのSQLステートメントを手動で定義したい場合は、それらを使用しないでください。

それでも、私見ですが、これは、DB関連のロジックをすべてコントローラーレイヤー内に配置する必要があるという意味ではありません。これは「ファットコントローラー」アプローチと呼ばれ、肥大化した保守不可能なコードにつながる道です。単純なCRUDプロジェクトに使用できますが、それを超えると、実際の「モデル」の存在が要求されます。

あなたはMVCを気にかけているようです。TDDについてもお読みください。ある賢者はかつて「レガシーコードはテストのないコードだ」と言っていました。自動化された単体テストが「実際の」コードと同じくらい重要であることを学ぶと、エンタープライズアプリケーションに非常に多くのレイヤーが存在する理由と、モデルレイヤーをコントローラーから分離する必要がある理由を理解できます。すべて(プレゼンテーション、ビジネスロジック、データの永続性)を実行しようとするコードのブロックは、簡単にテストすることはできません(ちなみにデバッグすることもできません)。

編集

「モデル」は少しあいまいな用語です。どこを見ているかによって、少し違う意味になることがあります。たとえば、PHP e Rubyプログラマーは、これをActive Recordの同義語として頻繁に使用しますが、これは正確ではありません。他の開発者の中には、「モデル」は単なるDTOの一種であると信じているようですが、これも正しくありません。

私はむしろウィキペディアで見られるようなモデルの定義を使用します:

MVCの中心的なコンポーネントであるモデルは、ユーザーインターフェイスに関係なく、問題のあるドメインの観点からアプリケーションの動作をキャプチャします。モデルは、アプリケーションのデータ、ロジック、およびルールを直接管理します。

したがって、モデルは、ほとんどのMVCアプリケーションで最大かつ最も重要なレイヤーです。そのため、通常、ドメイン、サービス、データアクセスなどのサブレイヤーに分割されます。モデルは通常、ドメインを介して公開されます。これは、コントローラーが呼び出すメソッドがそこにあるためです。ただし、データアクセス層も「モデル」に属しています。データの永続性ビジネスロジックに関連するものはすべてそれに属します。

于 2011-02-23T16:59:32.127 に答える
9

ほとんどの実際の状況では、ユーザーからのデータはデータベースに直接入りません。

多くの場合、検証、フィルタリング、または変換する必要があります。

モデルレイヤーの役割は、通常、これらの操作を実行することにより、データがバックエンドストア(通常はデータベース)に適切に到着することを確認することです。これは、コントローラー(スキニーコントローラー、ファットモデル)の責任ではなく、責任ではありません。データベースエンジン自体の。

言い換えると、モデルレイヤーは、データの処理方法を担当します(つまり「認識」します)。

最新のMVCフレームワークのほとんどは、Railsなどのデータ有効性要件に関するコントラクトを指定する方法を提供します。

これがhttp://biodegradablegeek.com/2008/02/introduction-to-validations-validation-error-handling-in-rails/からの例です:

class Cat
  validates_inclusion_of :sex, :in => %w(M F), :message => 'must be M or F'
  validates_inclusion_of :vaccinated, :in => [true,false]
  validates_inclusion_of :fiv, :in => [true,false]
  validates_inclusion_of :age, :within => 1..30
  validates_each :weight do |record, attr, value|
      record.errors.add attr, 'should be a minimum of 1 pound' if value and value  /^[01][0-9]\/[0-9]{2}\/[0-9]{4}$/
  validates_length_of :comment, :allow_blank => true, :allow_nil => true, :maximum => 500
end

ここで、データ妥当性要件のいくつかはデータベースで処理できないため、コントローラーで処理しないでください。これらの要件を変更すると、いくつかの場所でコードが破損する可能性があります。

したがって、このモデルは、データがドメインに対して一貫していることを確認するのに最適な場所です。

それについてはまだまだ多くのことが言えますが、実際の経験に動機付けられて、私にとって重要と思われる点に取り組みたいと思いました:)

于 2011-02-23T16:58:18.547 に答える
8

それはまったく無知な質問ではありません!MVC理論全体を単に無視して、好きなように実行するのではなく、質問しているという事実は素晴らしいことです。:-)

あなたの質問に答えるために:概念的には、モデルは単にあなたのデータに素晴らしい抽象化を提供します。モデルを使用すると、「必要なすべてのフィールドを取得するためにこの内部結合をどのように作成するか」という観点から考えるのではなく、「アプリケーションのオブジェクトがどのように相互に関連し、どのように相互作用し、どのように相互作用できるか」という観点から考えることができます。彼らから必要なデータを入手してください。」

ビューとコントローラーがプレゼンテーションをロジックから分離するのに役立つのと同じように、モデルは、データが実際にどこから来て、データが内部でどのように表されるかについて、アプリケーションのロジックを(とにかくユーザーの観点から)詳細から分離するのに役立ちます。

より具体的な例を示すと(完全に現実的ではない場合):理論的には、SQLクエリを介してすべてのデータをフェッチする方法でアプリケーション全体を記述できます。しかし後で、水平スケーリングが必要なため、noSQL(CouchDBなど)エンジンを使用したいと気づきました。

モデル(およびもちろん、両方のタイプのストレージを使用できるフレームワーク:-))を使用すると、すべての重要なデータがモデルと両方のビューおよび両方のビューを通じて一般的な方法ですでに表されているため、詳細について心配する必要はありません。コントローラはその表現に基づいて動作できます。

それらがないと、データフェッチを新しいバックエンドに適合させるためだけに、コードの大きなチャンクを書き直す必要があります。

そして、それは退屈なストレージ部分にあります。純粋なSQLでは、アプリケーションのオブジェクト(つまりビジネスロジック)間の相互作用を定義するのははるかに困難です。これは、SQLでは(おそらくとにかく)それを行わないためです。

それは完全な説明ではありませんが(それからはほど遠いです)、それが役立つことを願っています。

于 2011-02-23T16:59:06.433 に答える
3

モデルにはすべてのロジックが含まれている必要があります。コントローラは、ユーザーの操作に関連するロジックのみを担当します。ドメイン関連のすべての機能(「ビジネスロジック」と呼ばれるもの)をモデルに配置し、コントローラーコードから切り離す必要があります。このようにして、関心の分離とコードの再利用性を向上させることができます。

たとえば、ユーザーが自分自身に関する情報を入力し、食事療法の推奨を受け取ることができるアプリケーションを作成しているとします。

一方では、ユーザーが提供したデータをモデル部分の食事療法の推奨事項のリストに変換することに関連するコードを配置します。これには、データベースアクセスだけでなく、問題の問題(問題ドメイン)に関連する計算、アルゴリズム、および処理も含まれます。

一方、ユーザーをログインさせ、フォームを表示し、フォームデータを収集し、検証するためのコードをコントローラーに配置します。このようにして、たとえば、後でアプリにAPIを追加し(認証、ユーザーからのデータの取得、検証などに異なるコードを使用)、コードを再利用して(モデルから)結果を生成できます。

これは、モデルが何に適しているかの一例にすぎません。

于 2011-02-23T16:54:12.223 に答える
1

モデルが存在する場所や表現方法に関係なく、私は常にモデルをデータに関連付けます。MVCでは、Vはデータを表示し、Cは変更を処理します。コントローラ内のHashMapの画面に表示されるすべてのデータがある場合でも、そのHashMapはモデルと呼ばれます。

于 2011-02-23T16:47:16.513 に答える