Weitere ähnliche Inhalte
Ähnlich wie マジックビーンズ (20)
Mehr von Akira Suenami (13)
マジックビーンズ
- 2. 自己紹介
• 末並晃(すえなみあきら)
• @a_suenami
• 髪切りました / 痩せました
• RubyとかPHPとかJavaScriptとか
• いわゆる”Web系”エンジニア
• どちらかというと自然キー/複合キー容認派
• どちらかというとNULL撲滅したい派
- 5. アクティブレコードとは
# 1 件取得
bug = Bug.find(1234) # SELECT * FROM bugs
!
# 新規作成
bug = new Bug.new
bug.summary = ‘保存時にクラッシュが発生’
bug.save # INSERT INTO bugs (summary) VALUES (‘保存時にクラッシュが発生’)
!
# 更新
bug = Bug.find(1234) # SELECT * FROM bugs
bug.summary = ‘保存時にクラッシュが発生’
bug.save # UPDATE bugs SET summary = ‘保存時にクラッシュが発生’ WHERE id = 1234
!
# 削除
bug = Bug.find(1234) # SELECT * FROM bugs
bug.delete # DELETE FROM bugs WHERE id = 1234
- 6. 弊害1: モデルがデータベーススキーマに依存する
• アクティブレコードを用いると、n 個のテーブルがある場合、n 個の
モデルクラスが必要になる。
• データベースをリファクタリングする際にモデルクラスだけでなく、
それを使う側のコードまで変更する必要がある。
- 7. 弊害2: CRUD 機能を公開してしまう
• アクティブレコードを用いると find, create, update, delete などの
メソッドを公開メソッドとして直接呼び出せてしまう。
• ビジネスロジックとして実装されたメソッドを利用せず、公開
CRUD メソッドを利用できてしまう結果、要件を満たさないコード
が書かれる可能性がある。
• 書籍中ではバグ担当者をアサインしたらメール通知するはずだが、
メール通知が迂回されてしまうという例で紹介されている。
• 仮に要件を満たせたとしても、公開 CRUD メソッドの利用はビジネ
スロジックがアプリケーション層まで流出する結果になる。また、
複数箇所に同じロジックが重複する可能性がある。
- 8. 弊害3: ドメインモデル貧血症をもたらす
• モデルがデータアクセスオブジェクトとしてしか利用されず、ビジ
ネスロジックの多くがアプリケーション層にあるコントローラーオ
ブジェクトやサービスオブジェクトに記述されている状態を「ドメ
インモデル貧血症」という。
• 参考: http://capsctrl.que.jp/kdmsnr/wiki/bliki/?
AnemicDomainModel
• CRUD メソッドを公開してしまった結果として起こりやすい。
• ビジネスロジックを持たないモデルと巨大で手続き的なサービスオ
ブジェクトで構成されることになり保守性が低下する。オブジェク
ト指向のカプセル化の考え方に完全に違反している。
- 9. 弊害4: ユニットテストが困難
• モデル、ビュー、コントローラ、すべてのレイヤーにおいてユニット
テストが困難になる。
• モデル: データベースと密結合になるため、本番と同等のデータベー
ススキーマを準備して実際に接続する必要がある。
• ビュー: モデルが単なるデータコンテナとして使われると表示処理に
も複雑なロジックが生じるため、実際のレスポンスとして返される
HTML を生成し、それに対してテストする必要がある。
• コントローラ: ビジネスロジックがアプリケーション層に漏れだして
いるため、ビジネスロジックのテストのために HTTP リクエストとレ
スポンスをエミュレートする必要があり煩雑になる。
- 10. “Railsの”アクティブレコードのさらなる弊害
Rails のアクティブレコードの場合、データベースに加えてフォームと
も密結合になる。
<%= form_for(@bug) do |f| %>
<div class="field">
<%= f.label :summary %><br>
<%= f.text_field :summary %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
- 12. アンチパターンの見つけ方
• 「モデルにカスタム SQL クエリを渡すにはどうすればいい?」
• モデルにカスタム SQL を渡す必要はない。クエリをカプセル化し、アプリ
ケーション層から隠ぺいする。
• 「複雑なモデル操作をすべてのコントローラにコピーすればいいのだろうか、
それとも、親の抽象コント ローラクラスに 1 回だけコーディングすればいいの
だろうか」
• どちらの方法でも安定性や保守性は得られない。複雑な手続きがあるのであ
ればモデルのメソッドとして公開する必要がある。
• 「モデルのユニットテストを行うために、データベースフィクスチャをもっと書
かなければならない」
• モデルのテストではなくデータアクセスのテストをしている可能性がある。
- 16. レイヤー化アーキテクチャ
• 「エリックエヴァンスのドメイン駆動設計」で紹介されているアー
キテクチャパターン。
• ある層の要素は同じ層の別の要素か、より下の層の要素にしか依存
しないことを原則とする。
ユーザ・インターフェース層ユーザへの情報の表示、ユーザからの入力の解釈を責務
として負う。
アプリケーション層
ソフトウェアがやるべき仕事を定義し、問題を解決でき
るようにドメインオブジェクト間の調整をする。ドメイ
ンに対する知識を持たず、薄く保たれる層。
ドメイン層ビジネス上の概念やビジネスルールを表す責務を負う。
インフラストラクチャ層上位のレイヤを支える技術的機能を提供することを責務
とする。
- 17. オブジェクトの責務の割当てパターン ( GRASP )
• 情報エキスパート ( Information Expert )
• 生成者 ( Creator )
• 疎結合性(Low Coupling)
• 高凝集性(High Cohesion)
- 18. ドメインモデル
• ドメインモデルについては「エリック・
エヴァンスのドメイン駆動設計」で詳し
く述べられている。
• ドメインモデルとは対象ドメインに関心
事をアプリケーションで表現したもので
あり、MVC アーキテクチャにおける本来
の「モデル」もそうであるべきである。
• エリック・エヴァンスの書籍では永続化
層とドメイン層の仲介役としてリポジト
リパターンが紹介されている。
- 19. プレーンオブジェクト
• データベースの構造に依存しないプレーンなオブジェクトはテストしや
すく、またテストの実行速度も速い。
• 特に実装言語が Java の場合、それが特定のフレームワークやアーキテ
クチャに依存してないことを強調するために POJO ( Plain Old Java
Object ) と呼ばれる。
• 他の言語でも同様に POXO ( X は言語の頭文字 ) と呼ぶケースはあ
る。
• ドメインモデルを正しく設計してビジネスロジックをそこに隠蔽すると、
コントローラやビューのテストではそれらのモデルをモックやスタブに
差し替えることができ、数多くの分岐をテストしなくてよくなる。