Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
エキスパートRails基礎
Search
yokoto
August 03, 2020
Programming
1
430
エキスパートRails基礎
20200803社内勉強会資料。
yokoto
August 03, 2020
Tweet
Share
More Decks by yokoto
See All by yokoto
ひとりメタプログラミングRuby勉強会
yokoto
0
180
LINEボットを作ってみよう
yokoto
0
46
Other Decks in Programming
See All in Programming
AI Agent 時代のソフトウェア開発を支える AWS Cloud Development Kit (CDK)
konokenj
6
800
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
680
イベントストーミング図からコードへの変換手順 / Procedure for Converting Event Storming Diagrams to Code
nrslib
2
1.1k
PHP 8.4の新機能「プロパティフック」から学ぶオブジェクト指向設計とリスコフの置換原則
kentaroutakeda
2
1k
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
2
660
ソフトウェア設計とAI技術の活用
masuda220
PRO
17
3.7k
AI時代の『改訂新版 良いコード/悪いコードで学ぶ設計入門』 / ai-good-code-bad-code
minodriven
23
9.6k
“いい感じ“な定量評価を求めて - Four Keysとアウトカムの間の探求 -
nealle
2
12k
マッチングアプリにおけるフリックUIで苦労したこと
yuheiito
0
190
効率的な開発手段として VRTを活用する
ishkawa
0
160
AIエージェントはこう育てる - GitHub Copilot Agentとチームの共進化サイクル
koboriakira
0
760
CDK引数設計道場100本ノック
badmintoncryer
2
480
Featured
See All Featured
Mobile First: as difficult as doing things right
swwweet
223
9.7k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.9k
Visualization
eitanlees
146
16k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
331
22k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
35
2.4k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.7k
GraphQLの誤解/rethinking-graphql
sonatard
71
11k
It's Worth the Effort
3n
185
28k
Art, The Web, and Tiny UX
lynnandtonic
299
21k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.4k
Navigating Team Friction
lara
187
15k
Transcript
エキスパートRails基礎 2020/08/03 横田 俊博
パーフェクトRails増補改訂版が 発売されました。
None
None
「Skinny Controller, Fat Model」
「Skinny Controller, Fat Model」 限界
> アプリケーションが対象とする問題領域が複雑に なると、この設計原則だけでは立ち行かなくなって しまいます。 > Railsのモデルはその構造上、単体ではうまく表 現できない種類のロジックがいくつかあり、問題の 複雑さが増すとこれらが目立つようになるからで す。 パーフェクトRuby
on Rails p.460
https://techracho.bpsinc.jp/hachi8833/2013_11_19/14738 2012年
- 中規模Web開発のためのMVC分割とレイヤアーキテクチャ - てめえらのRailsはオブジェクト指向じゃねえ!まずはCallbackクラス、Validatorク ラスを活用しろ! - 俺が悪かった。素直に間違いを認めるから、もうサービスクラスとか作るのは止め てくれ - Railsの太ったモデルをダイエットさせる方法について
- Fat Modelの倒し方 / how to deal with fat model - 3年以上かけて培ったRails開発のコツ集大成(翻訳)|TechRacho(テックラッ チョ)〜エンジニアの「?」を「!」に 2013年~
2020年
11-1. アーキテクチャパターンから見るRails
Railsの考え方を深く理解するための、 アプリケーションとアーキテクチャに関する用語 1. ドメイン - アプリケーションが対象とする問題領域 - 例)ユーザー、求人、物件、etc 2. ドメインモデル
- ドメインの構成概念に関連する属性と振る舞いを持ったオブジェクト - 例)User(id:, name:, email:, telephone:) 3. アクティブレコード - ドメインモデルとデータベースを対応付けるライブラリ - テーブル => クラス - レコード => クラスのインスタンス - カラム => インスタンスの属性
アクティブレコードのメリットとデメリット - メリット - データベースのテーブルとクラスが直接対応しているため、単純で理解しやす い。 - デメリット - 構造上、単体では複雑なドメインロジックを表現しきれない
=> Fat Model
単一責任の原則 - オブジェクト指向設計のための5つの設計原則である『SOLID』のS - Single Responsibility Principle(単一責任の原則) - Open-Closed Principle(オープン・クローズドの原則)
- Liskov Substitution Principle(リスコフの置換原則) - Interface Segregation Principle(インターフェース分離の原則) - Dependency Inversion Principle(依存関係逆転の原則) - クラスやメソッドを1文で説明できる - クラス(オブジェクト)が担う責任は1つに限定すべきである - クラスを変更するときの理由付けは、1つしかあってはならない - 1つのクラスは1つの仕事しかしない
11-2. 値オブジェクト
ドメインに固有の、「値」に関するロジック
> 一見問題がないように見えますが、電話番号や他の値に関す るロジックを実装していくと、すぐにUserモデルが肥大化していき ます。 パーフェクトRuby on Rails p.464
> PhoneNumberという値オブジェクトを導入することで、電話番 号に関するロジックがUserモデルから分離されました。
> これで、電話番号に関するロジックが増えたとしても、Userモデ ルが不要に肥大化することはありません。 > また、電話番号に関するロジックをどこに実装すべきかが明ら かになり、そのロジックを複数のモデルの間で簡単に再利用でき るようになりました。 パーフェクトRuby on Rails
p.465
11-3. サービスオブジェクト
> Railsでアプリケーションを開発していると、モデルに実装すると 不自然なドメインロジックが出てくることがあります。 > 代表的な例が、複数のオブジェクトを組み合わせて表現するロ ジックです。 > サービスオブジェクトは、このようなロジックを独立したオブジェ クトとして定義したものです。 パーフェクトRuby
on Rails p.466
> balance(残高)という属性を持つBankAccount(口座残高)モデルを例に説明していきます。 > Moneyという値オブジェクトを導入して、これを口座残高の表現に用いると、次のようになります。
> 口座間の送金ロジックを実装したいとしましょう。説明を簡単に するため、送金ロジックは資金の引き出しと預入に酔ってのみ構 成されるものとします。送金元口座、送金先口座、送金資金をそ れぞれfrom、to、moneyとすると、次のように記述できます。
> このロジックをどこに実装すべきかを考えてみましょう。 > 複数の口座オブジェクトの状態を更新していることから、 BankAccountモデルのインスタンスメソッドとして実装するのは 不自然です。 > クラスメソッドとして実装した方がまだ自然ではありますが、この ような複数のオブジェクトを操作するロジックを実装していくと、す ぐにBankAccountモデルが肥大化していきます。このようなとき、
サービスオブジェクトを導入すると良いでしょう。 パーフェクトRuby on Rails p.468
app/services/transfer_money_between_bank_accounts_service.rb > このようなロジックを適宜サービスオブジェクトに実装していけば、BankAccountモデルが 不要に肥大化することもありません。 > サービスオブジェクトは「状態を持たない」ことに注意してください。 > callメソッドはデータベースの内容というグローバルな状態は更新しているものの、インス タンス変数をはじめとした自身の状態は更新していません。
サービスオブジェクト導入時のポイント - モデルに実装すべきロジックまで実装しない - オブジェクトの属性の値を直接参照・更新しているような箇所があれば、その 操作を対応するモデルのインスタンスメソッドとして定義すべきではないか考え る。 - イベント(create, destroyなど)の見落としがないか確認する
- ロジックではなくイベントに注目して実装する場合、サービスオブジェクトではな くイベントを表現するモデルを導入する。 - サービスオブジェクトを実装するクラスの名前は、ある1つのドメインロジックを指す ものにし、このロジックを実行するためのクラスメソッド を1つだけ公開する - サービスオブジェクトを肥大化させないようにする - 例)callメソッド
PORO(Plain Old Ruby Object) - ActiveRecordを継承しないふつうのオブジェクトのこと - services/配下に作成するサービスオブジェクトもPOROと言えるが、models/ 配下にPOROを作成するルールの現場もあるっぽい -
Railsの太ったモデルをダイエットさせる方法について - 俺が悪かった。素直に間違いを認めるから、もうサービスクラスとか作る のは止めてくれ - ドメインモデルを記述するディレクトリとして、models/、services/以外にfinder/、 validator.、callback/、parameter/などを作成する現場もあるっぽい - Railsでやってしまいがちな保守性を下げてしまうコードとその解決策
おまけ: Fat Viewについて - Helperを使うのをやめてDecoratorを使ってみる - Presenter(Decorator) - Railsでは、あるモデルが持つ属性やロジックを利用して、表示に関するロジックを実装する オブジェクトのことを指す
Railsのアーキテクチャに関心を持って、 再利用性の高いコードを書けるようになりたい おわり