Share
Embed
今改めてServiceクラスについて考える 〜あるRails開発者の10年〜
Kaigi on Rails 2025 登壇資料
Tomohiro Hashidate
September 26, 2025
Transcript
44 slides
-
2024/09/07 福岡Rubyist会議04 懇親会にて @junk0612 「サービスクラスってどう思います?」 @joker1007, @onk 「オッ!サービスクラスの話?」 みたいな感じになりまして、 ちょうど近くに座っていた
@snoozer05 さんとビアバーに流れて議論する機会があった。 これを機にちょっと話をしたいなーと思っていたら、この前の関西Ruby会議08でもサービス クラスへの言及があって、話すなら今だなと思った。 9 -
2011年4月 エリック・エヴァンスのドメイン駆動設計 発売 (原著は2003年発売) 日本でサービスクラスという名前が語られることが増えた背景に、DDD本の影響があったこと は無視できない。 この発表にも内容への言及がいくつか出てくるが、DDDという手法を採用する・しないに関わ らず、自分達が解決したい業務ドメインに対する理解を深めることは、どんなソフトウェアを 開発する上でも重要な営みだと考えているため。 Railsのバージョンとしては3.1〜3.2ぐらいの時期で、ActiveRecordが今も残る形に変更さ
れ、Sprocketsが入り、多くのスタートアップで使われる様になってきた時代。 ちょうど自分もRailsで仕事が出来る様になった頃で、個人的には一番熱かったかも。 13 -
Fat Modelに対する問題意識 Railsがビジネスの現場で使われることが多くなった結果、あちこちでFat Modelが問題として 顕在化し始めた。 ActiveRecordの特性上、システム自体が複雑になると色々な箇所から参照される基盤となる クラスに多くの処理が記述され、複雑度が爆発し依存関係がとっ散らかって管理しきれなくな る、という問題がしばしば発生する。 それに対処するために、モデルを整理するテクニックがあちこちで語られる様になりました。 Rails
fat modelでググると2010年頃からそういうテクニックについて語られている記事が増 えているのが分かります。 この頃からサービスクラスについての言及も多く出てきます。 14 -
Railsのレイヤー分類はよく出来ている Railsの基本的なレイヤーはController, Model, Viewだけだ。Jobは非同期処理向けの Controllerと言える。 Controller: ユーザーからのリクエストをハンドリングし、モデルの処理結果を表 示するviewを選択する Model: RDB操作とビジネスロジック全部
View: 処理結果の表示 これをきっちり守るだけで大体どこに何があるか想像が付く。 人間が簡単に覚えて共通認識を作れるのはこの程度だという割り切りが見える。 こういう共通認識の力こそがフレームワークを活用する利点。 逆に言えば共通認識を破壊するとフレームワークの利点が失われる。 22 -
サービスクラスを使っても問題ないケース 一人、または少人数で開発していてすぐにコミュニケーションが取れる チームの大半が対象業務を十分に理解しており、読み易いコードを維持すること についての水準が高い こういう場合なら使っても問題ないし、見通しが良くなるケースもあると思う。個人開発なら 基本的に問題ない。 最低でも一人はここまで話した様なことが自分で説明できて、コードレビューに時間が割ける ことが必要。 今日のトークの入門FormObject冒頭でFormObject説明できる人~って聞いてて、あまり手が上がらなかったですね。 この説
明の難しさがチームで書くコードのクオリティを保つ難しさでもある。 23 -
サービスクラスとの違い Formクラスは画面やユースケース(つまり大体アクション)と紐付いている ActiveModel, ActiveRecordのインターフェースと親和性が高い Formという名前から想像できる具体的なイメージがある 元々はビューに表示するformヘルパーとの相性も考慮されていたが、昨今はJSで 組み立てることが多いので、この点は重要ではなくなってきた。 単なる名前と印象の問題では?と思うかもしれないが、業務としてのソフトウェア開発におい てそれは物凄く重要である。チームメンバーが納得できる名前を付けられるかどうかがその後 の開発のしやすさに大きな影響を与える。
入門FormObjectで話をされていたのは機能的な分類だったが、自分は名前とそこから発生す る共通認識に注目している。 28 -
まずRDBと向き合う 参考: Identifying User Identity by moro dynamic! by moro
パーフェクトRails著者が解説するdeviseの現代的なユーザー認証のモデル構成に ついて by 俺 31 -
まずActiveRecord、ActiveModel、SQLを使いこな す 外から呼ばれるメソッドか、Validationか、Callbackかを適切に選択する Validation, Callbackに分岐を発生させない テーブル設計と組み合わせて状態管理をシンプルに ユニーク制約に影響を与える削除フラグを止めるとか STI, polymorphicは難しい、気を付けろ ちゃんとscope作って名前を付ける
joins, includes, preloadの違いを理解し、EXPLAINはすぐ確認できる様に 33 -
現実的だが楽な道ではない 参考: A Packwerk Retrospective (2024) - Shopify Packwerkの依存性検出には限界があるし、コンポーネントの責務をどう分離するかの示唆を 与えてくれる訳ではない。
特にドメインで分離した結果、機能面での依存が不自然になるのは非常に難しい問題で、簡単 に結論が出せる様な問題ではない。 コンテキストマッピングもコンポーネントの分割も、一度で上手くいく様なものではないの で、継続的に何度も判断を下し続けてコードとメンタルモデルを相互に改良し続ける必要があ る。(こういう行いをドメインモデリングの文脈では蒸留と呼ぶ)。 39