17

私が取り組んできたいくつかのMVCプロジェクトでは、神のクラスに有機的に成長した問題のあるコントローラーがいくつかあることが明らかになりました。

この質問は「何がどこに行くのか」という問題かもしれませんが、SRP(単一責任原則)、DRY(Do n't Repeat Yourself)、および物事を簡潔に「アジャイル」に保つことに関して重要な質問だと思います。そして、私はこれについて精通するのに十分な経験がありません(このパターンと一般的な設計で)。

1つのプロジェクトには、NutritionControllerがあります。時間の経過とともに、これらのアクション(多くはそれぞれのGET、POST、およびDELETEメソッドを含む)を含むようになりました。

Index (home controller)
ViewFoodItem
AddFoodItem
EditFoodItem
DeleteFoodItem
ViewNutritionSummary
SearchFoodItem
AddToFavorites
RemoveFromFavorites
ViewFavorites

次に、ExerciseControllerがあります。これには、検索やお気に入りのアクションなど、多くの同様のアクションが含まれます。これらを独自のコントローラーにリファクタリングして、そのようなものにする必要がありますか?

SearchController {
    SearchExercise
    SearchNutrition
    //... etc
}

FavoritesController {
    ViewNutritionFavorites
    AddToNutritionFavorites
    AddToExerciseFavorites
    EditNutritionFavorites
    EditExerciseFavorites
    //... etc
}

それらを別々のコントローラーに分割すると、必要な情報を処理するために、あるレベルで信じられないほど大きな依存関係が大きくなるように思われます。または、(M、V、またはCレベルのいずれかで)目的の効果を得るには非常に多くのフープをジャンプする必要があるため、処理が非常に難しい完全に汎用的な処理アプリケーションを使用することになります。

私はこれを間違った方法で考えていますか?たとえば、一般的なお気に入りオブジェクトを作成してから、それをスローするビューをコントローラーに決定させる必要がありますか?

*頭字語を綴って申し訳ありません-他の誰かがこの質問に出くわし、それらが何であるかについて無知な場合に備えて、私はそうしています

編集: 私が実行するすべてのロジックは、ほとんどサービスレイヤーで処理されます。たとえば、コントローラーは「新しい」FoodItemをサービスに送信します。すでに存在する場合、またはエラーがある場合、サービスはそれをコントローラーにバブルバックします。

4

4 に答える 4

12

私はあなたの最初のリストを責任に基づいて分割します:

HomeController

  • 索引

FoodItemController

  • ViewFoodItem
  • AddFoodItem
  • EditFoodItem
  • DeleteFoodItem
  • SearchFoodItem

NutritionController

  • ViewNutritionSummary

FavoriteController

  • お気に入りに追加
  • お気に入りから削除
  • ViewFavorites
  • SearchFavorites

DjangoのMVCへのアプローチは、責任を「アプリケーション」に分割し、それぞれが独自のモデル、コントローラー、さらには必要に応じてテンプレートを使用することです。ほとんどの場合、Foodアプリ、Nutritionアプリ、Searchアプリ、Favoritesアプリがあります。

編集:OPは、検索は各コントローラーに固有であると述べたので、これらのアクションを実行しました。ただし、検索は一般的なグローバルなものである場合もあるため、そのような場合はSearchControllerで十分です。

于 2009-06-21T16:17:23.047 に答える
2

ソビウトが言うようにしてください。コントローラーをシンプルに保ちたい。コントローラーの調整ロジックが多すぎるようです。ビューとモデルを接続する責任があることを忘れないでください。この調整ロジックは、おそらくサービスに分割する必要があります。

あなたがあなたのコントローラーが巨大な依存関係を成長させる可能性について言及しているので、私はこの感覚を得ます。FavoriteControllerが栄養について知り、お気に入りを行使する必要がある場合(同じビューに表示するため)、コントローラーをクラスのような2つのリポジトリに依存させないでください。代わりに、その調整動作をカプセル化します。たぶん、栄養と運動の両方のお気に入りを返す方法を知っているFavoritesServiceを作成します。そのサービスはNutritionFavoritesServiceとExerciseFavoritesServiceに委任する可能性があります。このように、コントローラーは1つの依存関係で終わり、物事をDRYに保ち、SRPを適用し、コントローラー以外の場所にビジネスロジックを集中させます。

于 2009-06-21T16:23:52.580 に答える
1

私はまた、この種のメンテナンスの頭痛の種を経験しており、「Rails」のような方法に固執することは、コントローラーを集中させて肥大化させないようにするのに非常に役立ちます。

変わった名前のアクションを追加していることに気付いた場合。ブログの例であるAddPostToBlogを使用するには、Createアクションを使用して新しいPostコントローラーを作成するためのフラグになります。

つまり、アクションがインデックス、新規、作成、表示、編集、更新、破棄のいずれのアクションでもない場合は、必要なアクションに固有の新しいコントローラーを追加します。

あなたの例のために。

SearchController {
    SearchExercise
    SearchNutrition
    //... etc
}

これをリファクタリングします...

   SearchExerciseController {
           Index   
   }

   SearchNutritionController {
           Index   
   }

これは、より多くのコントローラーを持つことを意味するかもしれませんが、私の意見では、これまでにない「神」コントローラーを拡張するよりも管理が簡単です。また、コントローラーがより自己文書化されていることも意味します。

例えば。SearchExerciseアクションは、ビューを返して演習を検索しますか、それとも実際に検索を実行しますか?パラメータと本文を確認することでこれを確認できますが、たとえば、[新規]と[作成]、または[編集と更新]アクションのペアほど簡単ではありません。

SearchController {
    SearchExercise       
}
于 2010-08-02T14:20:10.273 に答える
1

私はそのフレームワークにあまり精通していませんが、少し一般的なアドバイスを提供することができます。コントローラーは、おそらく、単一のアクションを完了する方法、または関連する一連のアクションを完了するために他の単一のアクションコントローラーを呼び出す方法のみを知っている必要があります。アクションからアクションに渡さなければならない情報は、おそらく何らかの形でモデルレイヤーを通過する必要があります。これは、その情報が基礎となるモデルに関連している可能性が高いためです。

于 2009-06-21T16:23:30.863 に答える