MVCでは、コントローラークラスに非アクションのプライベート関数を含めることをお勧めしますか?


10

コントローラークラスのアクション関数は、モデルからビューへのデータのフローを単純に制御するための多数のコード行で、巨大で厄介なものになる場合があります。ある時点で、これらの巨大な関数は、優れたコードの基本原則を完全に失うことになります。

これらの巨大なアクション関数をコントローラークラスで小さなプライベート関数に分割することは良い習慣と考えられるでしょうか、またはそのような最適化の必要性はモデルにそれらを追加する必要があることを意味しますか?

アクションに関連するように、コントローラーで小さい関数をプライベートとして使用することに投票しますが、モデルが巨大でぎこちない場合は、コントローラーはシンプルであることが望ましいという意見を聞いています。そして、どちらが最も好ましい方法であるか疑問に思っていました。

回答:


16

最高の類推ではないかもしれませんが、蜘蛛の巣について考えるのと同じ方法でコントローラーについて考えてください。その唯一の仕事は、クモ(下の層)が消化するハエ(要求)をキャッチすることです。ウェブは、小さいまたは大きいハエ(モデル)をキャッチして保持できます。クモのウェブの役割は獲物を消化することではありませんが、この目的で使用することはできます。薄くてきれいなウェブほど、クモは生計を立てやすくなります。

MVCアプリケーションに多少同じロジックを適用できます。説明する巨大で厄介な関数は、モデルの動作である可能性が最も高く、それらはモデルに属している必要があります(モデルはビューに表示されているオブジェクトだけではないことに注意してください)。モデルの動作が変化した場合、モデルを変更する必要があり、それを処理するコントローラーではありません。

また、それらをコントローラー内のプライベートメソッドとして保持することは、混乱を招き、維持するのを困難にするだけです。また、開発に関与している他の人々も、プロジェクトで以前にそれを行ったのを見たことがあるので、同じことをするように誘惑されるので、それは悪い習慣にもつながります。


創造的な類推のための+1。:)あなたは興味深い点を作ります。特に悪い癖の形成について。ありがとうございました。
デビッド「ハゲ生姜」

8

私が与えることができる最良の答えは、このテーマに興味のある人に強くお勧めする、Robert Martinの素晴らしい本「Clean Code」から引用することです。

関数の最初のルールは、それらが小さいことです。2つ目のルールは、それよりも小さいことです。

それをよく言うことはできません。同じ本の別の素晴らしい引用が適用されます:

関数は1つのことを行う必要があります。彼らはそれをうまくやるべきです。彼らはそれだけをすべきです。

コードをより多くの関数に分割する場合、コードの読みやすさを大幅に改善できる意味のある名前をこれらの関数に付ける必要があります。言うまでもなく、クラス外での使用を目的としていないすべての関数はプライベートである必要があるため、継承を介してコードを簡単に再利用できます。

コントローラの機能が多すぎる場合は、多すぎる可能性があります。次に、それをいくつかの独立した部分に分割するか、他の回答で述べたように、いくつかの関数をモデルに移動してみます。また、ビューがいくつかのロジックを持つことを許可されている非古典的なMVCフレーバーに従っている場合は、適合する場合はいつでも、いくつかの関数をそこに置くことができます。


1
ビジネスロジックをビューに組み込むことは「非クラシックMVC」ではなく、単に「悪いMVC」だと思います。当然、ビューには基本的な制御構造が必要ですが、ドメイン/ビジネスの問題ではなく、ユーザー/ UIの問題に合わせる必要があります。ビューの実際の機能はかなり恐ろしいです。
アーロンノート、2013

1
@Aaronaught私は「いくつかのロジック」で曖昧でした、私が念頭に置いていたのは、たとえば、ユーザーイベントと関数を配置してビューで処理するBackbone.jsライブラリです。従来のMVCでは、これはコントローラーの役割です。ただし、UIが変わるたびにビューとコントローラーの両方を調整する必要があるため、これは非現実的です。UIハンドラー関数をビューに配置すると、ビューを調整するだけで済みます。それは私の主観的な見方です-私は何かを逃していますか?
Dmitri Zaitsev 2013

1
何かがクライアント側で配信されるからといって、論理的にビューの一部であるとは限りません。ビューでのデータバインディングは確かですが、Backbone自体はMV *フレームワーク(MVCの一種、MVPの一種、どちらでもない)であり、クライアント側のスクリプトはそれに応じて編成する必要があります。そうでなければ、あなたはただハッキングしています。
アーロンノート、2013

0

MVCでは、コントローラーが可能な限り "薄い"ことを確認し、モデルが可能な限り非効率であることを確認します。

必要なロジックとヘルパー関数は、独立したスタンドアロンのヘルパークラスに入れられます。それは私のテストも非常に簡単にします(あなたはテストしています...そうですか?:D)コントローラをテストすることは悪名高いほど困難です。 httpあれこれ、そしてそれは苦痛ですが、それは故意の苦痛です。コントローラはHTTPとWebに密接にリンクされているため、これらすべてが必要です。Webアプリへのエントリポイントです。

ロジック関数とヘルパー関数は、Webとは関係ありません。それらは完全に環境にとらわれない(またはそうでなければならない)。それだけで、同じ場所に一緒に属していないことがわかるはずです。さらに、すべてのアプリケーションロジックをWebまたは特定のWeb実装に非常に密接に結び付けている場合、それを決して持ち歩けません。

すべてのデータベースエンティティ(mvcモデル、実際のdbエンティティではない)、ストレージ、ヘルパークラス、および独立したスタンドアロンdllのロジックを使用して、MVCサイトを開発しました。私たちにはすべて1つのWebサイトしかありませんでしたが、とにかくこのようにしました。

数か月前に、いくつかのフリンジシステムに関連するいくつかのデスクトップアプリを作成するように依頼されました。テスト済みのコードはすべて簡単に再利用できるため、これは簡単に実行できました。コードをWebプロジェクトに押し込んだり、コントローラーに組み込んだりした場合、これを行うことはできませんでした。


2
MVCのモデルは、ばかげていると思われない唯一のレイヤーです。スマートがモデルになく、コントローラーにもない場合、ビューのどこにあるのでしょうか?コントローラーもテストが難しくないはずです。ユニットテストを容易にするためにDIおよび偽物/モックを使用する機能は、他のフレームワークに対するMVCの魅力の1つです。私のコントローラーテストのほとんどは5行未満です。
アーロンノート、2013

ロジックを持つモデルに浸透するのではなく、ロジックを持つ「ヘルパー」クラスを使用します。モデルの中にどのようなロジックを入れますか?自分自身をロードして保存する方法を知っていますか?私は偽造/スタブが簡単であることに同意しますが、それはあなたのコントローラーを太らせ始める言い訳にはなりません。
宇宙飛行士2013

私はこの答えが意味を成していると感じていますが、それは間違って表現されています。あるいは、おそらく異なる用語です。
Simon Whitehead

3
「ヘルパー」クラスは、アーキテクチャー要素ではありません。それらは、M、V、またはCの一部です。どちらかわからない場合は、それらのヘルパーの結束が不足しています。「ヘルパー」という単語も、「ハンドル」、「実行」、「実行」、そして恐ろしいManagerの上位にランクされます。
アーロンノート2013

@SimonWhitehead:ほとんどの回答は意味がありますが、多くは正しくありません。残念ながら、これは「モデル」の意味の誤解を助長するか、重要なビジネスロジックをその外部に置くことを推奨するかのいずれかです。私はMVCサイトを無数の「ヘルパー」で維持するという疑わしい喜びを感じました-彼らは恐ろしいです。
アーロンノート2013

-2

Dmitri Zaitsevとspacemanのすばらしい回答のほかに、以下がPHPにも当てはまるかどうかはわかりません。自動テストの可能性がないため、プライベートメソッドを回避する必要があります。

はい、メタプログラミングや依存性注入を使用してプライベートメソッドをテストすることもできますが、コードの可読性に大きな影響を与えるため、行うべきではありません。

常にKISSの原則を覚えておいてください:単純で愚かである。


5
つまりないプライベートメソッドを回避するための十分な理由、また、MVCアーキテクチャとは何の関係もありません。あなたはプライベートメソッドをテストしようとしないでください、それらはパブリックメソッドのテストでカバーされるべきです。それらをカバーできない場合、それはクラスが複雑すぎてリファクタリングが必要であることを示しています。それはあなたがプライベートメソッドを持っていてはいけないという意味ではありませんし、(これがあなたが本当に意図したものではないことを私は心から望んでいます)代わりにそれらはパブリックであるべきです。
アーロンノート、2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.