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

Scala未経験のチームと共にScalaで新機能をリリースするまで

 Scala未経験のチームと共にScalaで新機能をリリースするまで

D108fe90711121e47b934341d5fbd3b4?s=128

TAKAHASHI Osamu

April 14, 2020
Tweet

Other Decks in Programming

Transcript

  1. Scala 未経験のチームと共に Scala で新機能をリリースするまで 2020-04-14 Scala 関⻄勉強会 TAKAHASHI Osamu 1

  2. 今⽇話すこと これまでScala 未経験だったメンバーが 「(Scala は)なんか難しくてとっつきにくいと思ってたけど、実 際書いてみたら、まあ難しいけど思ってたほどとっつきにくくはなか ったし、書いてて楽しかった」 と⾔ってくれるまでにやったことについて、という 概ねエモい話です 2

  3. 流れ ⾃⼰紹介 前提 チームのアプローチ 私のアプローチ まとめ 3

  4. ⾃⼰紹介 TAKAHASHI Osamu twitter: @zerosum_ フリュー株式会社 ピクトリンク事業部 開発部 システム再構築PJ ソフトウェアエンジニア

    サーバサイドアプリケーション Java 2 年 > Scala 4 年 > Java 2 年 > 最近はちょいちょいScala 4
  5. ピクトリンクとは サービスとしてのピクトリンク プリ画像をスマートフォンでDL できるサービス 2011 年リリース 前⾝としてフィーチャーフォン向けのサービスがあった 5

  6. ピクトリンクとは サーバサイドアプリケーションはjvm のエコシステムを利⽤してい る Java Servlet Tomcat Seasar2 Spring 6

  7. 開発したモノ サービスのバックエンドAPI の⼀つ とある社外サービスのAPI との通信を⼀⼿に引き受ける ピクトリンク本体との間をシンプルなREST API で通信 7

  8. Why Scala? 8

  9. Why Scala. チームメンバーの中でScala 得意な⼈のほうが多かった Scala 書ける⼈の割合が組織変更によって上がった 9

  10. チームメンバー 私 Scala でのプロダクト開発経験あり ドメイン知識はそれなり K さん Scala でのプロダクト開発経験あり チームへの参加は最近で、ドメイン知識はあまりない

    N さん Scala でのプロダクト開発経験なし Java でのプロダクト開発経験とドメイン知識は豊富 10
  11. チームのアプローチ 1. プロトタイプ作成 2. アーキテクチャ決定 3. ドメインの議論 <-> 実装 11

  12. プロトタイプ作成 この時点でのメンバーは私1 ⼈ ⽬的 社外サービスのAPI 仕様の検証 ビジネスサイドの要求を満たすか? 技術要素の検証 ビルド環境の整備 (特に初めてのメンバーが)環境構築で躓かないか

    とにかくハードルを下げる 12
  13. プロトタイプ作成 の裏で、N さんには「実践 Scala ⼊⾨」を読んでもらって いた 質問があったらとりあえず聞 いてくださいとも 13

  14. アーキテクチャ決定 Clean Archetecture の考え⽅を採⽤ ⽅針と詳細 ビルドレベルで依存の⽅向を制約した sbt is good //

    ↓ いわゆるutilities だが, ここが膨れるとヤバいので薄く保っている lazy val base = project in file("modules/base") // ↓ いわゆるビジネスロジック lazy val domain = (project in file("modules/domain")).dependsOn(base) // ↓JDBC やhttp client などへの依存はここ lazy val interface = (project in file("modules/interface")).dependsOn(base, domain) // ↓ アプリケーション全体の結合. フレームワークとかへの依存はここ lazy val api = (project in file("api")).dependsOn(base, domain, interface) 14
  15. アーキテクチャ決定 ⽬的 当初は「⽅針が詳細に依存できない」ことを⽬指した 「そこ、密結合したらまずくない?」を排除したかった DB のテーブル構造に依存した「ドメインオブジェクトのよう なもの」が⽣まれる余地を排除したかった 副次的な効果 「⽅針に近い部分の実装に集中できる」という状況ができた これは⽬からウロコという感じ

    15
  16. アーキテクチャ決定 ⾔葉(⽅針)を決める entity : 識別⼦とライフサイクルを持ってるやつ repository : entity のライフサイクルに関する振る舞い usecase

    : ユースケース単位で⾒たアプリケーションの振る舞い DDD とCrean Archetecture の⽤語が混じっているが、実装時に「この 振る舞いはどういう性質( repository 的、 usecase 的)だろうか」と 考えれば、どこで実装するべきか迷わなくなることを重視。 ( もちろん最初からきっちり分かれてたわけではなかった) 16
  17. アーキテクチャ決定 やらないことを決める 「Scala の型システムを駆使してClean Archetecture 」 こういうのは問題解決のためにScala を使ってきたチームが、 さらに問題にぶち当たったところで考えること 「どこで実装するべきか迷わなくなることを重視」

    17
  18. 議論 〜 実装 とにかくホワイトボードに書き出す ユースケースから始めて、徐々に概念を抽出する 18

  19. 議論 〜 実装 エラーハンドリングの⽅針を最初に決める ユースケース中で「どう失敗したか」は重要な概念 Scala のエラーハンドリングは柔軟で便利だが、初学者は迷いや すいと思った 具体的には ユースケースの中で現れた失敗は

    Either で扱う ライブラリ由来の例外は、上記に該当しない限り投げっぱなし try ~ catch や scala.util.Try は、ビジネスロジックの中では使 わない 19
  20. 議論 〜 実装 合意が取れた時点で仮のシグネチャとscaladoc を書く 可能ならこの時点でユニットテストのテストケースだけ列挙する Nothing is good /**

    [ 客] が[ 商品] を購⼊する. * - [ 残⾼] が⾜りない場合は「残⾼不⾜」として失敗する * - 購⼊に成功したら[ 購⼊履歴] を記録し, [ 残⾼] を[ 商品] 価格の合計だけ減らし, [ レシート] を発⾏する * * @param items 購⼊する[ 商品] のリスト * @param balance 購⼊時に[ 客] が持っている残⾼ * @return 購⼊に成功した場合は`Receipt` を返却する. * 残⾦不⾜で購⼊に失敗した場合は`Error.BalanceShotage` を返却する */ def purchace(items: Seq[Item], balance: Int): Either[Error, Receipt] = ??? 20
  21. 議論 〜 実装 ここまで来たらチームの誰でも実装できる状態になっている 悩む場合 議論が⾜りていない → 議論に戻る ⾔語仕様 →

    ⼝頭質問/ コードレビューでの指摘など ⽅針が不明瞭な箇所がある → 決める 21
  22. 私のアプローチ プロトタイプを作成して以降は、ほとんど実装をしなかった これは意図的にでもあるけど、結果的にでもある K さんとN さんのペアプロが⾃然発⽣していて、それがうまく回 っていた 22

  23. 私のアプローチ やっていたこと 各所で⽅針を決める 体系的な知識は書籍に任せ、質問に細かく答える コードレビュー 実装で悩んでいそうな兆候を⾒逃さないこと 23

  24. 結果 予定よりちょっと早めにリリースできた N さん「(Scala は)なんか難しくてとっつきにくいと思ってたけ ど、実際書いてみたら、まあ難しいけど思ってたほどとっつきにく くはなかったし、書いてて楽しかった」 24

  25. まとめ ⽅針と詳細という考え⽅が助けになった 「⽅針に近い部分の実装に集中できる」という状況は、最初のス テップとしてよかったと思う コミュニケーションを分厚くする ⼝頭、レビュー、議論。⼿段は何でも良い とにかく⾔葉を尽くす 25