Pro Yearly is on sale from $80 to $50! »

似非サービスクラスの殺し方 / #ginzarb

似非サービスクラスの殺し方 / #ginzarb

ぎんざRuby会議LT資料

A5e5ee2fb9e4ce3c728ed9e3ef6e916f?s=128

Tomohiro Hashidate

August 05, 2017
Tweet

Transcript

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

  2. 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万かかると言われて、 マジお金が無くて辛い。
  3. なんちゃら 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 !!)
  4. 今一度、 サー ビスクラスについて語ろう そして、 こういうのをちくちく直してコー ドを読める様にする 不毛な仕事が無くなります様に……。

  5. この話におけるサー ビスクラスとは いわゆるドメインサー ビス ユー ザー が利用する機能そのものを表現するクラス アプリが提供している業務の名前で呼ばれる ユー ザー

    を作る機能 ‑> C r eat e U s erS erv ice 領収書を登録する機能 ‑> R egist erR eceiptS erv ice ~~ するに明確な名前を付けたもの
  6. サー ビスクラスという名前のややこしさ アプリケー ションサー ビスとドメインサー ビス 前者はビジネスロジック自体の外側にあるもの 後者はビジネスロジックの機能の一表現 R ailsは

    DDD に余り親和性が無いため、DDD のパター ン を取り込むことが難しいのもややこしさを助長する R ailsにおいては複数のモデルに跨るトランザクション管 理のためのクラスと考えておけば概ね大丈夫
  7. サー ビスクラスにおいて最も重要なこと それは適切な名前が付けられるかどうか 機能名が付けられない様なものはサー ビスで はない

  8. おかしな名前の例 <モデル名>::S erv ice (何をするのか分からん) <モデル名>S t or age S

    erv ice (何をするのか分からん) A ccessB u ilder (サー ビスではないし、B u ilder パター ンですらない) 全体的に一連の手続きを表わすものでも何でもないが、 app/s erv ices の 下にある。 こんなの無いだろと思うかもしれませんが、 実際にあったんだから 仕方がない。
  9. 名前が曖昧 ≒ 仕様が曖昧 適切な名前が付いていないものは、 書いている本人も何 をやりたいか良く分かっていない もしくは、 仕様に対して真剣に向き合っていない 結果、 責任が不明確なクラスが生産され、

    メンテしづら いコー ドがはびこる ‑> 似非サー ビスクラス
  10. 似非サー ビスクラスの問題点 ややこしい処理をただ押し込めただけ 強烈に分岐があり、 テスタビリティが悪い 一つのクラスで色々 やり過ぎ app/models を読めばいいのか、 app/s

    erv ices を読めばいいのかさ っぱり分からない 特にapp/s erv ices に < 動詞> S e r v i c e 以外のクラスを置いている人は、 本気で反省した方が良い。 R ails が何のために a p p 以下のディレクトリを区切っていると思ってい るのか。 どこにどういう性質のものがあるかすぐ分かるための規約である。
  11. 延々 キレ続けたおかげで、 最近はこういうの が新しく増えることはほぼ無くなった

  12. あるべきサー ビスクラスの形 T railblazerの O perationクラスに学ぶ 仕事はフロー コントロー ルとエラー ハンドリングだけ

    コンテキストを順番に受け渡し、 結果を返す 結果は成功か失敗かが分かる様になっている
  13. サンプルコー ドで示すサー ビスクラス 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以外で持ってよいメソッドはエラー ハンドルぐらい。
  14. 良くないサー ビスクラスのシー ケンス図 問い合わせの嵐により、 とてもテストしづらい。

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

  16. 主要な処理は AR モデルか、 もしくは入れ子に した別のクラスに移譲する 似非サー ビスクラスの処理はとにかく AR のモ デルに戻していくのが早道

    特にエンティティモデルに対して状態を確認 しにいってる処理はエンティティ側が持って るべき処理であることがほとんど 行き場が無ければ、T railblazerの様に子サー ビスを作っても良い
  17. ここまで理解した上で、 サー ビスクラスが必 要な時には作ってもいい しかし、 ここまでの話に実感を伴っていない 場合、 余計なことはせずに AR モデルに処理を

    書いておく方が安全 そして、 名前がちゃんと付かないものを絶対 にサー ビスクラスにしないこと!!
  18. サー ビスクラスをより良く使うために 最低でもこれぐらいは読んでおくこと エリック・ エヴァンスのドメイン駆動設計 (定番であり入口) オブジェクト指向設計実践ガイド 特に単一責任の原則、 デメテルの法則をしっかり守ること リー

    ダブルコー ド 名前付けの重要さや、 処理フロー の抽象化レベルを揃えること について
  19. 良いコー ドと共にあらんことを