Slide 1

Slide 1 text

似非サー ビスクラスの殺し方 @ joker1007

Slide 2

Slide 2 text

self.inspect @joker1007 R epr o inc. CTO R u by/R ails flu ent d/embu lk D ocker/ECS B igqu ery/EMR /H iv e/P r est o クレカで40万ぐらい不正使用され、T hinkp adがぶっ壊れて修理に出し たら31万かかると言われて、 マジお金が無くて辛い。

Slide 3

Slide 3 text

なんちゃら R uby会議歴 東京 R u by 会議スピー カー 関西 R u by 会議スピー カー x3 T okyuR u by 会議 L T 王 R u byK aigi日本酒スー パー バイザー 東京 R u by 会議日本酒仕入れ R u byK aigi L T x3 名古屋 R u by 会議スピー カー 大江戸 R u by 会議 N inja ぎんざ R u by 会議 L T (NEW !!)

Slide 4

Slide 4 text

今一度、 サー ビスクラスについて語ろう そして、 こういうのをちくちく直してコー ドを読める様にする 不毛な仕事が無くなります様に……。

Slide 5

Slide 5 text

この話におけるサー ビスクラスとは いわゆるドメインサー ビス ユー ザー が利用する機能そのものを表現するクラス アプリが提供している業務の名前で呼ばれる ユー ザー を作る機能 ‑> C r eat e U s erS erv ice 領収書を登録する機能 ‑> R egist erR eceiptS erv ice ~~ するに明確な名前を付けたもの

Slide 6

Slide 6 text

サー ビスクラスという名前のややこしさ アプリケー ションサー ビスとドメインサー ビス 前者はビジネスロジック自体の外側にあるもの 後者はビジネスロジックの機能の一表現 R ailsは DDD に余り親和性が無いため、DDD のパター ン を取り込むことが難しいのもややこしさを助長する R ailsにおいては複数のモデルに跨るトランザクション管 理のためのクラスと考えておけば概ね大丈夫

Slide 7

Slide 7 text

サー ビスクラスにおいて最も重要なこと それは適切な名前が付けられるかどうか 機能名が付けられない様なものはサー ビスで はない

Slide 8

Slide 8 text

おかしな名前の例 <モデル名>::S erv ice (何をするのか分からん) <モデル名>S t or age S erv ice (何をするのか分からん) A ccessB u ilder (サー ビスではないし、B u ilder パター ンですらない) 全体的に一連の手続きを表わすものでも何でもないが、 app/s erv ices の 下にある。 こんなの無いだろと思うかもしれませんが、 実際にあったんだから 仕方がない。

Slide 9

Slide 9 text

名前が曖昧 ≒ 仕様が曖昧 適切な名前が付いていないものは、 書いている本人も何 をやりたいか良く分かっていない もしくは、 仕様に対して真剣に向き合っていない 結果、 責任が不明確なクラスが生産され、 メンテしづら いコー ドがはびこる ‑> 似非サー ビスクラス

Slide 10

Slide 10 text

似非サー ビスクラスの問題点 ややこしい処理をただ押し込めただけ 強烈に分岐があり、 テスタビリティが悪い 一つのクラスで色々 やり過ぎ app/models を読めばいいのか、 app/s erv ices を読めばいいのかさ っぱり分からない 特にapp/s erv ices に < 動詞> S e r v i c e 以外のクラスを置いている人は、 本気で反省した方が良い。 R ails が何のために a p p 以下のディレクトリを区切っていると思ってい るのか。 どこにどういう性質のものがあるかすぐ分かるための規約である。

Slide 11

Slide 11 text

延々 キレ続けたおかげで、 最近はこういうの が新しく増えることはほぼ無くなった

Slide 12

Slide 12 text

あるべきサー ビスクラスの形 T railblazerの O perationクラスに学ぶ 仕事はフロー コントロー ルとエラー ハンドリングだけ コンテキストを順番に受け渡し、 結果を返す 結果は成功か失敗かが分かる様になっている

Slide 13

Slide 13 text

サンプルコー ドで示すサー ビスクラス c l a s s R e g i s t e r H o g e h o g e S e r v i c e d e f i n i t i a l i z e ( m o d e l A , m o d e l B , m o d e l C ) d e f e x e c u t e # 起動以外のp u b l i c メソッドは持たせない A c t i v e R e c o r d : : B a s e . t r a n s a c t i o n d o r e s u l t A = m o d e l A . d o _ s o m e s h i n g A r e s u l t B = m o d e l B . d o _ s o m e t h i n g B ( r e s u l t A ) m o d e l C . d o _ s o m e t h i n g C ( r e s u l t B ) e n d r e s c u e n i l e n d e n d 可読性のために一時的な状態やメソッド抽出をプライベー トメソッドで 行える様にインスタンスメソッドレイヤー に処理を定義する方が良い。 特にクラスレイヤー で色々 やるとマルチスレッド時に危険。 ex ecut e以外で持ってよいメソッドはエラー ハンドルぐらい。

Slide 14

Slide 14 text

良くないサー ビスクラスのシー ケンス図 問い合わせの嵐により、 とてもテストしづらい。

Slide 15

Slide 15 text

目指すべき形 目指すは大きな V 字 問い合わせずに命じる 責任範囲の集約境界を意識する

Slide 16

Slide 16 text

主要な処理は AR モデルか、 もしくは入れ子に した別のクラスに移譲する 似非サー ビスクラスの処理はとにかく AR のモ デルに戻していくのが早道 特にエンティティモデルに対して状態を確認 しにいってる処理はエンティティ側が持って るべき処理であることがほとんど 行き場が無ければ、T railblazerの様に子サー ビスを作っても良い

Slide 17

Slide 17 text

ここまで理解した上で、 サー ビスクラスが必 要な時には作ってもいい しかし、 ここまでの話に実感を伴っていない 場合、 余計なことはせずに AR モデルに処理を 書いておく方が安全 そして、 名前がちゃんと付かないものを絶対 にサー ビスクラスにしないこと!!

Slide 18

Slide 18 text

サー ビスクラスをより良く使うために 最低でもこれぐらいは読んでおくこと エリック・ エヴァンスのドメイン駆動設計 (定番であり入口) オブジェクト指向設計実践ガイド 特に単一責任の原則、 デメテルの法則をしっかり守ること リー ダブルコー ド 名前付けの重要さや、 処理フロー の抽象化レベルを揃えること について

Slide 19

Slide 19 text

良いコー ドと共にあらんことを