Skinny Controllers, Skinny Models

  • 1,965 views
Uploaded on

7 つの実装パターンと Code Climate を使った実際のリファクタリング実践の紹介です。

7 つの実装パターンと Code Climate を使った実際のリファクタリング実践の紹介です。

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,965
On Slideshare
0
From Embeds
0
Number of Embeds
5

Actions

Shares
Downloads
0
Comments
0
Likes
8

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Skinny Controllers, Skinny Models M3 Tech Talk #m3dev Kazuhiro Sera @seratch
  • 2. RubyKaigi 2013 •  LT しました(rspec-kickstarter) •  席に戻ったら Gemfile に追加! •  今日は Refactoring Fat Models with Patterns という講演の内容とその実践に ついて紹介します •  興味を持った方は、動画が公開されている ので後で観てみてください https://vimeo.com/68611168
  • 3. @brynary •  Bryan Helmkamp •  Code Climate 創業者 •  顧客の Ruby コードを解析して品質・セ キュリティ改善を支援するサービス •  OSS なら無料、以下は Gistub の例 •  https://codeclimate.com/github/ seratch/gistub/
  • 4. Code Climate: Rating
  • 5. Code Climate: Code Smell
  • 6. Code Climate: Classes
  • 7. ブログエントリ •  7 Patterns to Refactor Fat ActiveRecord Models •  http://blog.codeclimate.com/blog/ 2012/10/17/7-ways-to-decompose-fat- activerecord-models/ •  さらに改善されたコード例を GitHub で公開 している(RubyKaigi での発表で使用) •  https://github.com/codeclimate/ refactoring-fat-models
  • 8. Rails ActiveRecord •  Pro: シンプルさ •  Con: DB のテーブルと 1:1 を強いられる
  • 9. Rails アプリでの失敗例 •  適切にデザインされたオブジェクト指向の コードはラビオリに例えられる •  時折、カルゾーネみたいに一カ所に詰め込 んだ Rails コードを見かける・・
  • 10. Skinny Models •  Fat Models とよく言われるが Model も Skinny であるべきなんでは?
  • 11. Fat Models との戦い •  Controller が肥大化するよりはマシ? •  既存の AR(ActiveRecord) model に責 務を持たせていくとどんどん肥大化 •  最悪のケースは神オブジェクトが誕生 •  @brynary は、定番の実装パターンをうま く Rails の model のリファクタリングに 適用する方法を提案している
  • 12. アンチパターン •  ただし、安易に mixin として module に 切り出すのはアンチパターン •  mixin は形を変えた継承 •  がらくたを突っ込む引き出し(コードを module に移して include するだけ) •  たくさん mixin された class だとどんな オブジェクトか把握するのが大変になる
  • 13. 7 つの実装パターン •  Value Objects •  Service Objects •  Form Objects •  Query Objects •  View Objects •  Policy Objects •  Decorators
  • 14. Value Objects •  おなじみ Value Object •  immutable な値を保持するクラス •  保持する値によって比較可能 •  何らかのロジックを持つ attribute(また はその小さな集合)が適している •  具体例:PhoneNumber、Money、 Ratingなど
  • 15. Service Objects •  複数の model を利用する場合 •  外部のサービス、API と連携する場合 •  複雑なロジックを実装する場合 •  既存の model の主たる責務でない場合 •  Strategy パターンを適用したい場合 •  普通 ActiveModel ではない
  • 16. Form Objects •  一つのフォームで複数の AR model を更 新したい場合に有効 •  ActiveModel にする •  Form の save の内部で複数の AR model の save を呼び出す •  標準の accepts_nested_attributes_for は @brynary 的には非推奨 •  複雑になったら永続化処理を Service に
  • 17. Query Objects •  バッチ用 or 複雑な条件の SQL を AR の scope やクラスメソッドにせず Query Object として分離 •  初期化時に AR::Relation オブジェクトを 渡すようにすると合成可能になる •  TrialQuery.new(Account.where(…)).fin d_each do ¦e¦ … end
  • 18. View Objects •  View のためのロジックを AR model に 書かない(エラーメッセージ生成など) •  AR model を保持するクラスを定義し render にはこちらを渡すようにする •  helper に AR model を渡す実装よりも、 リファクタリングが促進される •  多様な UI に対応する場合にも有効
  • 19. Policy Objects •  AR model を参照はするが主たるドメイ ンではないロジック(分析のための判定 など)を分離する •  例:メール配信対象?アクティブユーザ? •  AR model を保持するクラスとして定義 •  他との違い:Policy は read な処理だけ Service は write も含む、Query は SQL 実行と result set を yield に渡すだけ
  • 20. Decorators •  Decorator パターンを適用して callback 地獄を回避する •  例:save メソッドを数珠つなぎにする (AR の Order#save で orders テーブル に insert -> DHW に通知 -> 受付完了 メールを送信)
  • 21. 実践してみた •  実際にパターンを使って Gistub のリファ クタリングをしてみた
  • 22. パターンを実践する前
  • 23. パターンを実践した後
  • 24. やったこと •  使ったパターンは Service Objects だけ •  単に Controller から Service に切り出し ただけだと、今度はその新しい Service のスコアが悪かった(当たり前) •  複雑度の高すぎるメソッドを名前を付け られる単位に分割 •  コードの重複を共通化
  • 25. 改善の過程
  • 26. 今日から出来ること •  盲目的に AR のクラスメソッドにしない •  AR でないモデルもどんどんつくる •  Controller に AR model 呼び出しをズラ ズラ書くより Service にする •  複雑なフォームは Form を導入する •  AR に表示用ロジックを持たず View Object でラップして表示処理に渡す
  • 27. まとめ •  既に実践されているものも多いが、パター ンに名前がついて言語化されることは大事 •  最初はシンプルでよい(パターンのやりす ぎは over engineering) •  アプリが育っていく中で規模に応じたリ ファクタリングは必要になっていく •  ただし、十分なコードカバレッジは必須
  • 28. アプリ規模とアーキテクチャ
  • 29. Q&A M3 Tech Talk #m3dev Kazuhiro Sera @seratch Any Question?