3

IRC から質問をここに移動します。

問題: 良い形にしたいコード ベースに飛び込んでしまいました。私たちはいつもそうではありませんか?

その精神で、(テスト カバレッジのように) いくつかのカバレッジを追加した後、このタスクを支援するためにいくつかの既知のリファクタリング/改善を適用しました。これが私がやったことです(実際にはもっと多くのことをしましたが、これらは私の質問に関連するビットです):

  1. モデル、コントローラー、さらにはビューで実行されるいくつかのタスクをオフロードするために、いくつかの PORO オブジェクトを追加しました。
  2. *decent_exposure* を使用して、ビュー レイヤーがあったインスタンス変数地獄を取り除きました。
  3. ビューに多くのロジックが含まれないように、draperを使用していくつかの for-views デコレーターを実装しました。
  4. 複数のモデルを生成するアクションのプレゼンターを追加しました。

今、私は(楽観的に)これがすべてうまくいくと予想していました. それは実際には優れていますが、台所の流し以外をすべて投げた後、私はそれがはるかに優れていると期待していました. そうではありません。

文字通り 1 回のアクションで 10 ~ 15 個のパーシャルをレンダリングするビュー レイヤーがあるため、コントローラーまたはビュー レイヤーで何かを変更できるか心配です。アカウントのメンバーを「メンバー」または単に「ユーザー」と呼ぶことにしたときはいつでも、このすべてのパーシャルを実行したくありません。モデルレイヤーはもっと大きな変更が予定されているので、これは気にしています。

私が最初に考えた(そして今でも立っている)のは、愚かな見方をすることです。ビューレイヤーの大部分で、レンダリングしているモデルについてまったく知らないようにしたいのです。モデルから必要なデータを抽出し、HTML をレンダリングするという 2 つのことを行う方法を知っている中間オブジェクトが必要です。ここで SRP に違反していると言う前に、このオブジェクトの本当の責任は、「モデルをエンド ユーザーに表示すること」と読むことができます。

過度に単純化して、私の意見 (少なくともこれらの前述のもの) を次のようにしたいと思います。

= some_object.render
= another_object.render

デコレータ パターンのように聞こえますし、プレゼンター パターンのようにも聞こえますが、少なくともこれは私が経験したことです。

それから、私は MVC (少なくとも Rails が公開する MVC) から大きく逸脱するだろうと考え始めたので、これが最善の解決策であるかどうかを知りたいと思いました (この時間制約では明らかでほとんど不可能な REWRITE 以外)。 、だから私はショットを作ることにもっと自信があります。

したがって、その文脈で、私の本当の質問は次のように要約されます。

a) MVP、MVVM、MV への切り替えは、この問題の適切な解決策ですか?

b) そうである場合、この some_object.render ビュー スタイルに使用できる最適なソリューションについて教えていただけますか?

c) そうでない場合、大幅に書き直されるのに数時間かかる可能性のあるモデル レイヤーを使用して、一般に、これらのパーシャルとビューの間の強い依存関係を回避する方法を教えてもらえますか?

d) あなたがここに来ないことを願っています: YAGNI, 後で修正しますか? 私はそれが必要になると確信しています。

私の頭をよぎり、IRC に持ち込んだ別のオプションがあります。実際には、タイトルの精神ではなく、有効なオプションです (目の前のタスクにはやり過ぎだと思いますが)。

e)サービスレイヤーを追加し、ビューをそのサービスレイヤーの「論理」モデルにマップして、ビューとは無関係に物理モデルを変更できるようにします。

4

2 に答える 2

3

主に正確な問題があいまいであるため、この質問に答えるのは困難です。興味深いことに、これが前進するために助けが必要だと感じる理由でもあると思います。

要約する:

すでに次のようにリファクタリングしています:

  • ダムビュー
  • きれいな景色
  • テスト済みのビュー

それでも、あなたの主な不満:

文字通り 1 回のアクションで 10 ~ 15 個のパーシャルのようにレンダリングされるビュー レイヤーがあります。コントローラーまたはビュー レイヤー内のものを変更する能力が心配です。このすべてのパーシャルを通過したくありません

私がすること:

関連するビューをマージすることで、「ビューファイルが多すぎます」を解決します。

コードが実際にどのように変化しているかに合わせてビューを整理することで、「ビューコードが見つかりません」を解決します。

ノート:

2 つのアンチパターンに直面しているようです。

  • ソリューションのスプロール (過分解)
  • パターンの使いすぎ

10 ~ 15 個のパーシャルが過剰に思える場合は、そうかもしれません。各部分はコード ベースで再利用されていますか? それらをより適切にグループ化できますか (したがって、3 ではなく 1 をレンダリングできます)? 2 つのパーシャルを作成するのではなく、1 つのパーシャル データを送信してレンダリングを調整することはできますか?

あなたは「責任の分担」が行き過ぎているように思えます。膨大な量のビューがあなたの邪魔をしています。多分再構成は前進する道ですか?

MVP、MVVM などに注目するのは間違った方向です。パターンにこだわると、少し傷つくかもしれません。例えば、

# how is this:
= some_object.render

# different from this?
= render "some_object"

ビューは確実に「モデルをエンドユーザーに表示する」責任があります

私はあなたの痛みを感じます.コード量だけが問題になる場合があります. ローテクではありますが、組織化とグループ化は、それに取り組むための最良の方法になる可能性があります.

于 2012-08-21T02:34:18.987 に答える
1

あなたの質問に対する一般的な答えではありませんが、あなたが言及したこの特定の問題について:

アカウントのメンバーを「メンバー」または単に「ユーザー」と呼ぶことにしたときはいつでも、このすべてのパーシャルを実行したくありません。

Rails i18n を使用します。これは実際の i18n のためだけではなく、このように、ユーザーに表示可能な用語やその他の言語を完全に削除するための優れた方法でもあります。

それはあなたの質問に対する一般的な答えへの手がかりになるかもしれません.1つの答えだけでなく、コードのさまざまな側面の保守性と分かりやすさを改善するためのさまざまな答えがあるかもしれません.

これは難しいことです。おそらく、魔法の弾丸があると言っている人を信用しないでください。彼らが言うようにやれば、すべてが素晴らしいものになるでしょう。特に、詳細を知らずにそれを言っている場合は、あなたが私たちに与えたあなたのプロジェクト/問題の一般的な説明。

しかし、プレゼンター/デコレーターのアプローチが物事をより良くするように思われる場合、それは何も悪いことではないと思います。シンプルにすることを忘れないでください。純粋な魔法のない Ruby デコレーター/プレゼンターで済むのであれば、不思議なように実装された派手な Rails エンジンを使用するよりはましだと思います。物事を可能な限り単純にする (そして単純にするのではなく) ことを常に忘れないでください。そうすれば、あなたは正しい道を進んでいます。(はい、物事をシンプルに保つために、物事をひどく複雑にしすぎたことに後で気付くことがあります。おっと)。

私があなたの質問だと思うことの別の部分については、

モデルのレンダリングに使用する部分的な名前を返すメソッドを提供するために、モデルにデコレータを使用することがあります。私がそれを行ったとき、解決策に完全に満足しているかどうかはわかりませんが、モデルの部分的な名前を推測するRails独自の魔法の方法とそれほど違いはありません(おそらく-何らかの方法でカスタマイズまたはパラメータ化できますが、誰もそれを覚えたり見つけたりすることはできません)。よりも優れていると思いますsome_object.render。代わりに、もっと好きrender :partial => some_object.render_partial_name, :object => some_objectです。

または、あなたが言及した中間オブジェクトを提供することもできます。これは基本的にプレゼンタータイプのもので、実際には上記とかなり似ていますが、オブジェクトグラフは異なります。

PresentWidget.new( some_object ).render

ただし、ActionViewを適切にレンダリングできるように、別のオブジェクトを作成するには、いくつかの魔法を使用する必要があります。いくつかのマジック レール プレゼンター エンジンは、それを行うのに役立ちます。しかし、私はいつもあまりにも多くの魔法で気分を害します.

または、Cells を見ることもできます。こういう問題でCellsが欲しいと思うことはよくありますが、個人的に使い始めると「魔法使いすぎ、レールと格闘しすぎ」でいつも諦めてしまいます。

および同様のスタックオーバーフローの質問で、これも特に見事な解決策はありませんが、アイデアが得られるかもしれません:オブジェクトの動的部分名

ただし、すべてのオプションの中で、個人的にモデル自体に方法を与えることはしません。#render独立したプレゼンターを ActionView にフックして呼び出せるようにすることrenderは 1 つのことですが、モデルをそのようにフックすることはさらに悪いようです。

そして最後に、書き直しは書き直しよりも優れていると確信していますか?

この種のアーキテクチャを熟考し、実装することにこれほど多くの時間を費やした後、最初から書き直した方が早かったことに気付くかもしれません。書き直してきれいにする方法が明らかであるが、この奇妙なメタリガマロールを上に追加してきれいにする方法が明らかでない場合...明らかなことだけを実行しないのはなぜですか? このようなものを上に追加すると、当然、書き換え/リファクタリングも行われます。

于 2012-08-21T03:14:02.860 に答える