Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

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

ぎんざRuby会議LT資料

Tomohiro Hashidate

August 05, 2017
Tweet

More Decks by Tomohiro Hashidate

Other Decks in Technology

Transcript

  1. 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万かかると言われて、 マジお金が無くて辛い。
  2. なんちゃら 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 !!)
  3. この話におけるサー ビスクラスとは いわゆるドメインサー ビス ユー ザー が利用する機能そのものを表現するクラス アプリが提供している業務の名前で呼ばれる ユー ザー

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

    DDD に余り親和性が無いため、DDD のパター ン を取り込むことが難しいのもややこしさを助長する R ailsにおいては複数のモデルに跨るトランザクション管 理のためのクラスと考えておけば概ね大丈夫
  5. おかしな名前の例 <モデル名>::S erv ice (何をするのか分からん) <モデル名>S t or age S

    erv ice (何をするのか分からん) A ccessB u ilder (サー ビスではないし、B u ilder パター ンですらない) 全体的に一連の手続きを表わすものでも何でもないが、 app/s erv ices の 下にある。 こんなの無いだろと思うかもしれませんが、 実際にあったんだから 仕方がない。
  6. 似非サー ビスクラスの問題点 ややこしい処理をただ押し込めただけ 強烈に分岐があり、 テスタビリティが悪い 一つのクラスで色々 やり過ぎ app/models を読めばいいのか、 app/s

    erv ices を読めばいいのかさ っぱり分からない 特にapp/s erv ices に < 動詞> S e r v i c e 以外のクラスを置いている人は、 本気で反省した方が良い。 R ails が何のために a p p 以下のディレクトリを区切っていると思ってい るのか。 どこにどういう性質のものがあるかすぐ分かるための規約である。
  7. あるべきサー ビスクラスの形 T railblazerの O perationクラスに学ぶ 仕事はフロー コントロー ルとエラー ハンドリングだけ

    コンテキストを順番に受け渡し、 結果を返す 結果は成功か失敗かが分かる様になっている
  8. サンプルコー ドで示すサー ビスクラス 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以外で持ってよいメソッドはエラー ハンドルぐらい。
  9. 主要な処理は AR モデルか、 もしくは入れ子に した別のクラスに移譲する 似非サー ビスクラスの処理はとにかく AR のモ デルに戻していくのが早道

    特にエンティティモデルに対して状態を確認 しにいってる処理はエンティティ側が持って るべき処理であることがほとんど 行き場が無ければ、T railblazerの様に子サー ビスを作っても良い