2009-06-10 12 views
7

コンピュータサイエンスでは、それぞれの方法が1つのことと1つのことだけを行うべきであると教えてきました。私たちは、次のgiven as examples of good practiceのようなMVCのアクションを見ること、その後少し混乱しています:Asp.Net MVCアクション - 懸念の分離/単一の責任原則

[AcceptVerbs(HttpVerbs.Post), Authorize] 
    public ActionResult Edit(int id, FormCollection collection) { 

     Dinner dinner = dinnerRepository.GetDinner(id); 

     if (!dinner.IsHostedBy(User.Identity.Name)) 
      return View("InvalidOwner"); 

     try { 
      UpdateModel(dinner); 

      dinnerRepository.Save(); 

      return RedirectToAction("Details", new { id=dinner.DinnerID }); 
     } 
     catch { 
      ModelState.AddModelErrors(dinner.GetRuleViolations()); 

      return View(new DinnerFormViewModel(dinner)); 
     } 
    } 

基本的にコードのこの作品は、多くの機能を提供します。

  1. はアクションにアクセスする方法を定義します - 投稿のみ
  2. アクションにアクセスできるユーザーを定義します - (User.Ident - dinnerRepository
  3. は、状態情報にアクセス -
  4. が永続化メカニズムにアクセス認可ity.Name)
  5. は強く、オブジェクトを入力してNameValueCollectionのに変換 - のUpdateModel()
  6. 指定3可能ActionResultsし、それぞれのコンテンツ - InvalidOwner /詳細/編集ビュー

は、私にはこれがためにあまりにも多くの責任のように思えます1つの方法。またのような一般的なシナリオを扱っていない、すなわち、かなり単純なアクションです:

  1. は、ビジネスルールを確認する -
  2. ナビゲーションパスを「ユーザの入力を信用しない」 - 成功するには、常に「詳細」
  3. に戻ります保存
  4. 戻り値の型が異なる - 誰かがグリッドから「編集」を呼び出してJsonResultが必要ですか?
  5. エラー処理の改善 - データベースはGetDinner中にアクセスできない場合(ID)
  6. 追加のビューデータを構築YSOD - ドロップ用SelectListsダウンリスト

があまりにもこの単一の方法を中心に必要なテストの量を言及していませんすなわち、FormCollection/UserIdentity/Authorization Provider/Repository/etcのためのmocking/fakingです。

私の質問は、私たちのコントローラーのアクションに多大な影響を与えるのを避けるにはどうすればよいですか?

私は"opinions"が特に "サンダードームの原則"という大きなコンセプトだと思う傾向があります。私はFubuMVCの建物に関わる人たちとその理由について大いに尊敬していますが、私は今すぐ使えるものが必要です。

編集 - 私はこのような何かをしていたようだ - Opinionated Controller。私はそれをMVCプレビュー5のためにさらに検討する必要があります。私はそれを自分で更新する必要があるかもしれません。

+0

非常に良い質問! –

答えて

1

あなたの投稿で少し混乱しています。まず、あなたはこの行動が多くのことをしていると訴え、その後はそれ以上のことをしていないと文句を言う。

追加する編集:

正直なところ、これは非常に複雑なコントローラのアクションではありません。それがベストプラクティスの例であるかどうかは議論の余地がありますが、それよりずっと簡単にはならないでしょう。私はあなたが別のルーチンにそれをいくつか破ることができると思うが、ある時点では、その行を描画する場所を決定する必要があります。最終的には、プログラマはソフトウェアを書く必要があります。デザインプリンシパルはすばらしいですが、もし私たちがあまりにも硬すぎると、何も構築されることはありません。

+0

@クリスプ - それほど不平を言うわけではありませんが、私は、現実の世界では、この単純な例よりもはるかに複雑になると簡単に述べています。このような複雑さに対処する最善の方法は何かを知りたい。 – Neil

+0

実際、これはおそらくこのような動作で見られる複雑さのかなり普通の例です。これには取り組まないシナリオもあります。これらの他の状況に対処する必要がある場合は、それらを処理するアクションを書き換えます。 あなたは何を考えていると思いますが、このアクションは何を達成する必要がありますか?ビューからモデルへのデータを取得し、ユーザーに何らかの応答を表示します。あなたが探していることがその一部であるなら、素晴らしい。そうでなければ、おそらくどこか別の場所に行くはずです。 – Chrisb

+0

上記の例でModelErrorsを追加するなど、多くのアクションで共通のことが起こっている場合は、それを別の方法に分けることができます。あなたが投稿した例は、実際にそれを行います。 サンプルアプリケーションには、その目的のためのコードを含むControllerHelpersというファイルがあります。 – Chrisb

3

私にとって、この方法は、ウェブフォームから受け取った編集値でモデルを更新することのみを行います。

これを実行するには、いくつかのことが必要ですが、それらは原子的でよく定義されています。モデルのこの部分をどのように更新する必要があるかを変更する必要がある場合、これは検索して更新するコントローラアクションです。

Thunderdomeの原則の1つである「コントローラーは軽くなければならない」は、ここでビジネスルールがチェックされているため、満たされていないと主張できます。しかし、NerdDinnerはこれを余分なレイヤーに置くのは無理な非常に簡単なアプリです。

このメソッドがあまりにも多すぎる場合は、メソッド内に複数のステートメントを置くことが禁止されている言語を見つける必要があります。

+0

@ Dave-私は同意しません、この簡単な例は少なくとも2つのことを行います - モデルを更新し、プログラムフローを指定します。これらの要件のいずれかが変更された場合は、このメソッドを更新する必要があります。私はむしろモデル更新の結果に基づいてプログラムの流れを決定する他の方法よりもむしろいくつかの方法があります。 私はあまりにもペナルティを受けていません。1つの声明= 1つのことを実行してください。 – Neil

0

私はそれはまだ「アクション」は絶対単一responsbilityに適合しない場合があり、このrequired..for最小アクションにやっていると思います - 属性があるが、それは単一のアクションである

  1. このの方法がHTTP.Postでのみ機能し、それを使用しようとしているIDが承認されている必要があることをASP.NETに伝えます。 - 良いセキュリティ。だからこの時点では何も実際には行われていない。これらは、サーバーに何をチェックするかを伝えるだけです。

    すなわちないHTTP.post 方法は、そしてあなたのいないリストの場合は、文句を言わない仕事が動作しない場合。

  2. ユーザーIDがディナーのIDと一致するかどうかを確認する検証があります。 - サニティーチェック。

  3. これはStrong Type Checkingに基づいています - モデルの現在のオブジェクトが新しいデータで更新されたことを確認するだけです。リポジトリにSave()が呼び出されます。これはまだアクションの1つのユニットにあります。モデルを更新して、saveを呼び出して持続させることができます。

  4. 妥当性チェックは、モデルにRuleViolationsを追加し、ユーザーを問題のビューに戻すCatchで処理されます。つまり、対処するための応答性を渡している部分ビューを編集/作成します。

  5. セーブが機能している場合、つまり、ユーザーの「ワークフロー」を「詳細」に移動するだけです。つまり、フォームをメモリから消去して詳細に戻します。 IMHOは素晴らしい - 私たちはPOSTシナリオにあり、記憶に横たわっていないもの - 良い。

  6. フローを移動して詳細を戻さず、部分編集ビューのままにするほうが簡単です。

+0

特に6番に同意します。もちろん、ほとんどのアプリはNerdDinnerのような詳細なフォーマットでデータテーブル全体を表示するわけではないので、ユーザーを編集ビューに戻すだけでよいでしょう。 この方法は、多数のデータが急速に入力される場合に便利です。 – Chrisb

+0

@littlegeek - あなたの答えは、私が尋ねた質問のために何の助けもしていません。どのように/なぜこの行動が働くかを私に教えようと努力することに感謝します。問題は、それ以上の複雑さにかかわらず、そのような簡単な例についてあまりにも多くの懸念が混じっていると私はまだ感じています。私は、「シングルアクション」がリクエスト/レスポンス間に非常に多くの懸案事項を処理することになっているという概念に同意しないと思います。私はむしろ特定のハンドラにこれらの懸念を軽減することが大事です。 – Neil

-1

i「は、単一責任の原則」を持っている問題は、人々がやるということではありません常にセグメントのイベントと同じ - 他よりもいくつかのよりきめ細か。だから、すべてのアクションのより詳細な見方を簡単に見つけることができるように思われるが、最も単純なケースである。

関連する問題