太ったモデルと細いコントローラーは、神のモデルを作成するように聞こえる[終了]


91

私は特に、ファットモデルと細いコントローラーのアプローチを支持する多くのブログを読んでいます。Railsキャンプ。その結果、ルーターは基本的に、どのコントローラーでどのメソッドを呼び出すかを理解しているだけであり、すべてのコントローラーメソッドは、モデルの対応するメソッドを呼び出してビューを表示します。だから私はここで私が理解できない2つの懸念を持っています:

  1. コントローラーとルーターは、ルートに基づいて神のようなモデルでメソッドを呼び出す以外に、実際にはそれほど異なるタスクを実行していません。
  2. モデルがやりすぎです。電子メールの送信、関係の作成、他のモデルの削除と変更、タスクのキューイングなど。基本的に、データのモデリングと処理に関係するかどうかに関係なく、すべてを実行することになっている神のようなオブジェクトがあります。

どこに線を引くのですか?これは単に神のパターンに該当するのではないですか?

回答:


136

RailsをMVC設計パターンの定番として見るのは、最良のアイデアではないかもしれません。このフレームワークは、いくつかの固有の欠点(別の投稿で少し詳しく説明しました)で作成され、コミュニティはたった今、放射性降下物への取り組みを開始しました。DataMapper2 開発を最初の主要なステップとして見ることができます。

ある理論

そのアドバイスをする人々は、非常に一般的な誤解に悩まされているようです。だから、それを片付けることから始めましょう:モデルは、現代のMVC設計パターンでは、クラスでもオブジェクトでもありません。モデルはレイヤーです。

MVCパターンの背後にある中心的なアイデアは、懸念の分離であり、その最初のステップは、プレゼンテーションレイヤーとモデルレイヤーの分割です。プレゼンテーションレイヤーがコントローラー(ユーザー入力の処理を担当するインスタンス)、ビュー(インスタンス、UIロジックを担当)、およびテンプレート/レイアウトに分解されるように、モデルレイヤーもそうです。

モデルレイヤーを構成する主要な部分は次のとおりです。

  • ドメインオブジェクト

    ドメインエンティティ、ビジネスオブジェクト、またはモデルオブジェクトとも呼ばれます(混乱を招くため、後者の名前は嫌いです)。これらの構造は、人々が通常誤って「モデル」と呼ぶものです。彼らは、ビジネスルール(ドメインロジックの特定のユニットに対するすべての計算と検証)を含める責任があります。

  • ストレージの抽象化:

    通常、データマッパーパターンを使用して実装されます(この名前を乱用したORMと混同しないでください)。これらのインスタンスは通常、ドメインオブジェクトからの情報の取得とドメインオブジェクトへの取得を担当します。ストレージのいくつかの形式(DB、キャッシュ、セッション、Cookie、/ dev / null)があるように、各ドメインオブジェクトは複数のマッパーを持つことができます。

  • サービス:

    アプリケーションロジック(つまり、ドメインオブジェクト間の相互作用、およびドメインオブジェクトとストレージアブストラクション間の相互作用)を担当する構造。それらは、プレゼンテーション層がモデル層と相互作用するための「インターフェース」のように機能する必要があります。これは通常、Railsのようなコードでは、最終的にコントローラーになります。

これらのグループ間のスペースには、DAO作業単位リポジトリなどの構造もいくつかあります

ああ...そして、MVCアプリケーションと対話するユーザーについて(Webのコンテキストで)話すとき、それは人間ではありません。「ユーザー」は実際にはあなたのウェブブラウザです。

では、神々はどうですか?

怖いモノリシックモデルを使用する代わりに、コントローラーはサービスと対話する必要があります。ユーザー入力から特定のサービス(MailServiceまたはなどRecognitionService)にデータを渡します。このようにして、コントローラーはモデルレイヤーの状態を変更しますが、これは明確なAPIを使用して行われ、内部構造を変更することなく行われます(これにより、抽象化がリークします)。

このような変更は、即座に何らかの反応を引き起こすか、ビューインスタンスがモデルレイヤーから要求するデータのみに影響を与えるか、またはその両方になります。

各サービスは、任意の数のドメインオブジェクトとストレージアブストラクション(通常はほんの一握りです)と対話できます。たとえばRecogitionService、は記事のストレージの抽象化についてあまり気にすることができませんでした。

おわりに

このようにして、任意のレベルで単体テストを実行でき、カップリングが低く(正しく実装されている場合)、アーキテクチャが明確に理解できるアプリケーションを取得できます。

ただし、MVCは小規模なアプリケーション向けではありません。MVCパターンを使用してゲストブックのページを作成している場合、それは間違っています。このパターンは、大規模なアプリケーションに法と秩序を適用するためのものです。

PHPを第一言語として使用している人にとっては、この投稿が関連するかもしれません。これは、いくつかのコードスニペットを含むモデルレイヤーの少し長い説明です。


非常に便利で完全な答えです!MVCのアーキテクチャパターンをもう少し詳しく説明した本を知っていますか?特にモデルの部分では、誰もが誤って「モデルはデータを表し、他には何もしない」と誤解しています。そしてその多くのドメインオブジェクトの考えのような音ではなく、「モデル」 - > tomdalling.com/blog/software-design/...
thermz

1
@ thermz、afaik、MVCパターンのみを扱った本は本当にありません。私は通常、人々にPoEAAを読んでから掘りに行くように言っています。多分このリンクのリストは役に立つかもしれません。私は、人々がOOPの原則と概念をしっかりと理解していると、パターンが非常に理解しやすくなることに気づきます。
テレシュコ2013年

@tereško美しい答え。Hibernateはこれを実現しますか?私は、ここでの回答で確信していない- > stackoverflow.com/questions/1308096/...
Ankan-Zerob

@ Ankan-Zerobはお気づきかもしれませんが、私はJava開発者ではありませんが、Hibernateについて知っていることから、永続層の完全なツールセットを提供します。そこに記載されている内容の一部は提供されますが、完全なモデルレイヤーは提供されません
テレシュコ2014年

3
@johnnyは私の知る限りではありません。PHPのいわゆる「mvcフレームワーク」のほとんどは、Railsのバリエーションです。そして、コースの一部として、それらのほとんどにはいくつかのアクティブなレコードベースのORMソリューションが付属してます(これらのものは、DBの変更に対して非常に脆弱です)。このようなものをSF2.xまたはZF2.xで実装できます、フレームワークの目的は、特定のアーキテクチャーを実装/実施することではなく、ツールを提供することです。また、MVCに関しては、フレームワークではなくアプリケーションコードによって実装されます
tereško

5

「モデル」クラスが十分に実装されていない場合は、懸念事項が関係しています。モデルクラスは、電子メール(インフラストラクチャタスク)を実行するべきではありません。

本当の問題は、MVCのモデルが何を意味するかです。いくつかのメソッドを持つPOCOクラスに限定されていません。MVCのモデルとは、データおよびビジネスロジックを意味します。古典的なコアPOCOモデルのスーパーセットとして扱います。

ビュー====コントローラー====モデル--->ビジネスプロセスレイヤー->コアモデル

インフラストラクチャアセンブリとデータアクセスレイヤーを投入し、インジェクションを使用してそれをBPLに渡すと、プロセスは意図したとおりにMVCを使用します。

BPLはUoW /リポジトリパターンを呼び出し、ビジネスルールを実行し、注入されたオブジェクトまたはインターフェースパターンを介してインフラストラクチャ機能を呼び出すことができます。

したがって、コントローラーを細くするという推奨事項は、クラシックCoreモデルの「人物」クラスに50のメソッドがあり、Emailを直接呼び出す必要があることを意味しません。これは間違っていると考えるのは当然です。

コントローラは、直接呼び出された場合、インフラストラクチャクラスをインスタンス化してBPLまたはコアレイヤに注入する必要があります。ビジネス層、または少なくともクラシックオブジェクトモデルクラス全体で呼び出しを調整するクラスが必要です。とにかくそれは私の「ビュー」です;-)

MVCの一般的な見方については、wikiの説明http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

MVCの「M」について語る小さなブログ。http://www.thedeveloperday.com/skinny-controllers/


1
あなたが少なくとも同意しない場合は、あなたの見解を正当化するのに十分に礼儀正しく
phil soady

-1

単一のファットモデル(名前はAppまたはApplication)と、論理グループ(ビジネス、顧客、注文、メッセージ)に分割されたいくつかのファットモデルを区別できると思います。後者は私がアプリを構成する方法であり、各モデルは、リレーショナルデータベースのデータベーステーブルまたはドキュメントデータベースのコレクションにほぼ対応しています。これらのモデルは、データベースと通信する場合でも、APIを呼び出す場合でも、モデルを構成するデータの作成、更新、および操作のすべての側面を処理します。コントローラは、適切なモデルを呼び出してテンプレートを選択するというほとんどの原因となる非常に薄いものです。

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