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

Onboarding Process for Scala Team

Onboarding Process for Scala Team

ScalaMatsuri 2020 発表資料

Shunsuke Tadokoro

October 17, 2020
Tweet

More Decks by Shunsuke Tadokoro

Other Decks in Technology

Transcript

  1. Onboarding Process
    for Scala Team
    ScalaMatsuri 2020
    Scala
    チームのオンボーディング
    1

    View Slide

  2. The opinions expressed here are my own and
    do not reflect the view of any organization
    ここで⽰されている⾒解は私個⼈のものであり、いかなる組織の⾒解を反映す
    るものではありません。
    2

    View Slide

  3. About this talk
    This talk is for Scala teams welcoming newcomers
    aboard
    Why onboarding matters for Scala teams
    Onboarding practices
    technology knowledge
    business domain knowledge
    Onboarding also refines source code
    新メンバーを迎え⼊れるScala
    チーム向けに、なぜオンボーディングが重要か、
    私たちのプラクティス、オンボーディングがコードを洗練させるということに
    ついてお話しします。 3

    View Slide

  4. Background
    This talk is based on experiences in 3 teams
    Team size Newcomers Their Experienced Lang
    3 ~ 5
    2 Mid-careers
    1 Intern
    Java
    10 ~ 15
    3 Mid-careers
    3 Newgrads
    Java, Ruby, Python, JS, Go
    4 ~ 5
    2 Newgrads
    3 Interns
    Java, Python
    このセッションの内容は、3
    つのScala
    チームでの経験を元にしています。
    4

    View Slide

  5. Who

    Shunsuke Tadokoro @todokr
    Software Engineer @ BizReach, Inc.
    Robert Devlin
    Software Engineer @ BizReach, Inc.
    ⽥所 駿佑:
    株式会社ビズリーチ ソフトウェアエンジニア
    ロバート・デブリン:
    株式会社ビズリーチ ソフトウェアエンジニア
    5

    View Slide

  6. 6

    View Slide

  7. Scala & Team
    Scala
    とチーム
    7

    View Slide

  8. Scala is a "scalable" language
    Unique in its flexibility and expressiveness
    It enables developers and teams to change styles as
    they grow
    Procedural
    Object-Oriented
    Functional
    Scala
    は柔軟で表現⼒の豊かな⾔語。
    開発者やチームの成⻑に合わせてスタイルを変えていくことができる。
    8

    View Slide

  9. If the team chooses FP style
    Starts with procedural style...
    まずは⼿続き型のスタイルで始める...
    9

    View Slide

  10. If the team chooses FP style...
    As time goes by, the team applies FP style
    そして時は流れ、チームは関数型スタイルに
    10

    View Slide

  11. If the team chooses FP style...
    However, it's hard for newcomers
    to catch up with the team
    新メンバーのキャッチアップが⼤変
    11

    View Slide

  12. Why catching up matters
    The average half-life for software engineers is 3.2
    years
    「ソフトウェアエンジニアの半減期」は平均で3.2

    12

    View Slide

  13. Why catching up matters
    The average half-life for software engineers is 3.2
    years
    We want to minimize the time it takes for newcomers
    to maximize their performance
    新メンバーが最⾼のパフォーマンスを発揮するまでの時間を最⼩にしたい
    13

    View Slide

  14. Why catching up matters
    The average half-life for software engineers is 3.2
    years
    We want to minimize the time it takes for newcomers
    to maximize their performance
    Also, we want newcomers to remain with the team
    かつ、新メンバーが⻑く居続けてもらえるようにしたい
    14

    View Slide

  15. Employee Onboarding
    従業員オンボーディング
    15

    View Slide

  16. Definition: Employee onboarding
    “The process of assisting new hires in gaining a
    functional understanding of the skills and tasks
    required in their new role, helping them to develop new
    relationships with others in the workplace, and
    facilitating an understanding of the company culture
    and goals.”(Dr. Allison Ellis, Ph.D.

    「新⼊社員が新しい役割に必要なスキルとタスクを機能的に理解し、職場で他
    の⼈と新しい関係を築き、企業⽂化の理解を促進するプロセス」
    16

    View Slide

  17. What is employee onboarding good for?
    Productivity
    For a new employee to become fully productive, it takes eight
    months on average (AlliedHR)
    新規採⽤者が最⼤の⽣産性を発揮するまでに必要な期間は平均8
    ヶ⽉
    17

    View Slide

  18. What is employee onboarding good for?
    Productivity
    For a new employee to become fully productive, it takes eight
    months on average (AlliedHR)
    A new employee who had a sufficient onboarding programs gain
    full proficiency 34% faster than who didn't (Urbanbound)
    ⼗分なオンボーディングプログラムを受けた従業員は、そうでない従業員に⽐
    べて最⾼のパフォーマンスに達するまでの期間が34%
    短縮される
    18

    View Slide

  19. What is employee onboarding good for?
    Productivity
    For a new employee to become fully productive, it takes eight
    months on average (AlliedHR)
    A new employee who had a sufficient onboarding programs gain
    full proficiency 34% faster than who didn't (Urbanbound)
    Retention
    New employees who went through a structured onboarding
    program were 58% more likely to be with the organization after
    three years (Wynhurst Group)
    構造化されたオンボーディングを経験した新規採⽤者は、そうでない採⽤者に
    ⽐べて3
    年後の在職率が58%
    ⾼い
    19

    View Slide

  20. What is employee onboarding good for?
    Productivity
    For a new employee to become fully productive, it takes eight
    months on average (AlliedHR)
    A new employee who had a sufficient onboarding programs gain
    full proficiency 34% faster than who didn't (Urbanbound)
    Retention
    New employees who went through a structured onboarding
    program were 58% more likely to be with the organization after
    three years (Wynhurst Group)
    Organizations with a strong onboarding process improve new
    hire retention by 82% (Brandon Hall Group)
    強⼒なオンボーディングプロセスを持つ組織は、新規採⽤者の在職率が82
    %以
    上向上する
    20

    View Slide

  21. 21

    View Slide

  22. What this session focuses
    How to support newcomers to gain a understanding
    of the skills and tasks required in the team using Scala
    このセッションは「新メンバーがScala
    を使うチームに必要なスキルとタスクを
    理解することをどうサポートするか」にフォーカスします。
    22

    View Slide

  23. How shall we support?
    A viewpoint: The Professional
    Development Ladder by Steve
    McConnell, the author of the
    Code Complete
    スキルとタスクの理解をどう⽀えるか?
    ひとつの切り⼝が The Professional
    Development Ladder 23

    View Slide

  24. The capability for software professional
    “We have found that professional capability for
    software professionals is like a three-legged stool”
    「ソフトウェア開発者のケイパビリティは三本⾜の椅⼦のようなものであるこ
    とが分かった」
    24

    View Slide

  25. The capability for software professional
    “We have found that professional capability for
    software professionals is like a three-legged stool”
    1. Technology knowledge
    1.
    テクノロジーの知識
    25

    View Slide

  26. The capability for software professional
    “We have found that professional capability for
    software professionals is like a three-legged stool”
    1. Technology knowledge
    2. Business domain knowledge
    2.
    ビジネスドメインの知識
    26

    View Slide

  27. The capability for software professional
    “We have found that professional capability for
    software professionals is like a three-legged stool”
    1. Technology knowledge
    2. Business domain knowledge
    3. Software development best practices knowledge
    3.
    ソフトウェア開発のベストプラクティスの知識
    27

    View Slide

  28. The capability for software professional
    “We have found that professional capability for
    software professionals is like a three-legged stool”
    1. Technology knowledge
    2. Business domain knowledge
    3. Software development best practices knowledge
    オンボーディングでの問題は、テクノロジーの知識とビジネスドメインの知識
    28

    View Slide

  29. Our practice
    in gaining
    Technology Knowledge
    我々のプラクティス:
    テクノロジーの知識編
    29

    View Slide

  30. Our practice: Technology Knowledge
    Start from "Why we use Scala"
    Topics we choose
    Types
    Collection operation
    Composition of function
    「なぜScala
    を使うのか」から始める。
    私たちの場合は、「型」「コレクション操作」「関数の合成」。
    30

    View Slide

  31. Our practice: Technology Knowledge
    Start from "Why we use Scala"
    Topics we choose
    Types
    Collection operation
    Composition of function
    Patterns
    "Scaffolding" in Mob/Pair programming
    Introduce learning resources
    Quick-win tasks
    その他のオンボーディングでのテクニック。
    モブ/
    ペアでの"Scaffolding"
    、学習リソースの紹介、クイックウィンタスク。
    31

    View Slide

  32. Start from "Why we do Scala"
    Scala has many features and patterns. We cannot
    cover all in OJT/Off-JT
    Scala
    にはたくさんの機能とパターンがある。全てをOJT/Off-JT
    でカバーする
    ことはできない。
    32

    View Slide

  33. Start from "Why we do Scala"
    Scala has many features and patterns. We cannot
    cover all in OJT/Off-JT
    Therefore, we have to start with "Why we use Scala"
    What value do we see in Scala?
    What aspect affects our business?
    だからこそ「なぜ我々はScala
    を使うのか」から始める。どんな価値を⾒出して
    いるか?どんな性質が⾃分らのビジネスに影響を与えるのか?
    33

    View Slide

  34. Start from "Why we do Scala"
    Scala has many features and patterns. We cannot
    cover all in OJT/Off-JT
    Therefore, we have to start with "Why we use Scala"
    What value do we see in Scala?
    What aspect affects our business?
    Then, choose learning topics to concentrate on
    問いへの答えをもとに、⼒を⼊れるトピックを選ぶ
    34

    View Slide

  35. Learning topics we highlight
    私たちがハイライトする学習トピック
    35

    View Slide

  36. Learning topics we highlight
    Types: How to exploit the power of types
    型:
    その⼒をどう引き出すか
    36

    View Slide

  37. Learning topics we highlight
    Types: How to exploit the power of types
    Collections: Understand how the method works
    コレクション:
    メソッドの働きを理解する
    37

    View Slide

  38. Learning topics we highlight
    Types: How to exploit the power of types
    Collections: Understand how the method works
    Composition of functions: How to express logic
    cleanly
    関数の合成:
    ロジックをクリーンに表現する
    38

    View Slide

  39. Learning topics we highlight
    Types: How to exploit the power of types
    Collections: Understand how the method works
    Composition of functions: How to express logic
    cleanly
    We'll introduce how we unpack these topics.
    これらの学習トピックを、新メンバーにどのようにお話しているかをご紹介し
    ます。
    39

    View Slide

  40. Learning topic #1: Types
    トピック1:

    40

    View Slide

  41. Type: the set of possible values
    型:
    とりうる値の集合
    41

    View Slide

  42. Type: the set of possible values
    val id: String = fetchId(...)
    val name: String = fetchName(...)
    val age: Int = calcAge(...)
    型:
    とりうる値の集合
    42

    View Slide

  43. Type: the set of possible values
    val id: String = fetchId(...) // String: ∞
    val name: String = fetchName(...) // String: ∞
    val age: Int = calcAge(...) // Int: -2147483648 ~ 2147483647
    String
    が取りうる値: ∞
    Int
    が取りうる値: -2147483648 ~ 2147483647 43

    View Slide

  44. Type: the set of possible values
    val id: String = fetchId(...) // String: ∞
    val name: String = fetchName(...) // String: ∞
    val age: Int = calcAge(...) // Int: -2147483648 ~ 2147483647
    It's very rare to have an unbounded string or integer
    in a real-world domain
    現実の問題領域において、制限のない数値や⽂字列はほぼ存在しない。
    44

    View Slide

  45. Type: the set of possible values
    val id: String = fetchId(...) // String: ∞
    val name: String = fetchName(...) // String: ∞
    val age: Int = calcAge(...) // Int: -2147483648 ~ 2147483647
    It's very rare to have an unbounded string or integer
    in a real-world domain
    There's no special meaning or domain-specific
    restriction in String or Int
    String
    やInt
    に特別な意味はない。
    45

    View Slide

  46. Exploit the power of types
    型の⼒を引き出す
    46

    View Slide

  47. Exploit the power of types
    Value class: not to confuse values
    Value class:
    値を取り違えないようにする
    47

    View Slide

  48. Exploit the power of types
    Value class: not to confuse values
    ADT and pattern matching: to express control flow
    simply
    ADT
    とパターンマッチング:
    制御フローをシンプルに表現する
    48

    View Slide

  49. Exploit the power of types
    Value class: not to confuse values
    ADT and pattern matching: to express control flow
    simply
    Refinment Type: more type-safety & declarative
    validation
    Refinement Type:
    さらなる型安全性 &
    宣⾔的バリデーション
    49

    View Slide

  50. Value class
    Create a more specific, info-rich type and use it
    Not to confuse arguments
    Creating value class takes no labor in Scala
    case class AccountId(value: String) extends AnyVal
    case class AccountName(value: String) extends AnyVal
    val accountId: AccountId = AccountId("@todokr")
    val name: AccountName = AccountName("Shunsuke Tadokoro")
    Value class:
    より特定的で情報量の豊かな型
    50

    View Slide

  51. ADT and pattern matching
    An information system is a pack of junctions
    sealed trait IP
    case class IPv4(value: String) extends IP
    case class IPv6(value: String) extends IP
    アプリケーションは分岐の塊
    51

    View Slide

  52. ADT and pattern matching
    An information system is a pack of junctions
    sealed trait IP
    case class IPv4(value: String) extends IP
    case class IPv6(value: String) extends IP
    ip match {
    case IPv4(value) => // handle IPv4
    case IPv6(value) => // handle IPv6
    }
    アプリケーションは分岐の塊
    52

    View Slide

  53. ADT and pattern matching
    An information system is a pack of junctions
    sealed trait IP
    case class IPv4(value: String) extends IP
    case class IPv6(value: String) extends IP
    ip match {
    case IPv4(value) => // handle IPv4
    case IPv6(value) => // handle IPv6
    }
    The combination of ADT and pattern matching is a
    powerful way to express logic concisely
    ADT
    とパターンマッチングは、簡潔にロジックを表現する強⼒な⼿段
    53

    View Slide

  54. Refinement Type
    Handy techniques to harden type safety.
    refined
    A library refining types with type-level predicates
    より型安全性を⾼めるテクニック。refined
    というライブラリで実現。
    54

    View Slide

  55. Refinement type with refined
    // Define rule as type
    type AccountIdRule = MinSize[3] And MaxSize[10] And StartsWith["@"]
    type AgeRule = NonNegative
    ルールを型として表現する
    55

    View Slide

  56. Refinement type with refined
    // Define rule as type
    type AccountIdRule = MinSize[3] And MaxSize[10] And StartsWith["@"]
    type AgeRule = NonNegative
    // "refine" String and Int type
    type AccountIdString = String Refined AccountIdRule
    type AgeInt = Int Refined AgeRule
    String
    やInt
    を"refine"
    する
    56

    View Slide

  57. Refinement type with refined
    // Define rule as type
    type AccountIdRule = MinSize[3] And MaxSize[10] And StartsWith["@"]
    type AgeRule = NonNegative
    // "refine" String and Int type
    type AccountIdString = String Refined AccountIdRule
    type AgeInt = Int Refined AgeRule
    val accountId: AccountIdString = "@uryyyyyyyyy" // Compile error!
    val age: AgeInt = -1 // Compile error!
    ルールを満たさない値はコンパイルエラー
    57

    View Slide

  58. More practical example
    https://engineering.visional.inc/blog/168/scala-
    refined-newtype/
    Derive runtime validation logic from type
    Work with Circe & Doobie
    より実践的な例を、弊社エンジニアリングブログで公開しています。
    宣⾔的なランタイムバリデーション、JSON
    やDB
    ライブラリとの連携
    58

    View Slide

  59. Newcomer Take: Types
    新メンバーの感想:

    59

    View Slide

  60. Newcomer Take: Types
    Types are domain knowledge
    型 =
    ドメイン知識
    60

    View Slide

  61. Newcomer Take: Types
    Types are domain knowledge
    Controls expected behavior more closely
    型で、期待する振る舞いを保証できる
    61

    View Slide

  62. Learning topic #2: Collections
    トピック2:
    コレクション
    62

    View Slide

  63. An application is a pack of collections
    Members
    Products
    Purchases
    Shippings
    ...
    アプリケーションはコレクションの塊
    63

    View Slide

  64. Scala has a powerful collection library
    Provides highly abstract operations which are easy-to-
    use, concise and universal.
    Scala
    のコレクションライブラリは強⼒。
    簡潔で広く適⽤できる、⾼度に抽象化された操作。
    64

    View Slide

  65. Scala has a powerful collection library
    Provides highly abstract operations which are easy-to-
    use, concise and universal.
    However, teaching what those methods do easily isn't
    easy
    "scala".groupMapReduce(identity)(_ => 1)(_ + _)
    // Map(a -> 2, c -> 1, s -> 1, l -> 1)
    しかし、メソッドの働きを易しく教えるのは簡単ではない
    65

    View Slide

  66. Visual Scala Reference
    66

    View Slide

  67. 67

    View Slide

  68. Newcomer Take: Collections
    新メンバーの感想: コレクション
    68

    View Slide

  69. Newcomer Take: Collections
    Strictly typed collections enable flexibility
    map/collect/reduce/etc make data processing easy
    型付けされたコレクションが実現する柔軟性
    69

    View Slide

  70. Newcomer Take: Collections
    Strictly typed collections enable flexibility
    map/collect/reduce/etc make data processing easy
    Online resources cover this part of Scala well
    オンラインリソースもあります!
    70

    View Slide

  71. Learning topic #3: Composing
    functions
    71

    View Slide

  72. An application is also a pack of functions
    Composability of functions is important for evolving
    design and keeping it clean.
    アプリケーションは関数の塊。関数の合成のしやすさは、設計の進化とそれを
    クリーンに保つうえで重要
    72

    View Slide

  73. An application is also a pack of functions
    Composability of functions is important for evolving
    design and keeping it clean.
    How do we compose functions?
    How do we handle errors?
    関数同⼠をどのように組み合わせるか?
    エラーハンドリングをどうするか?
    73

    View Slide

  74. https://fsharpforfunandprofit.com/rop/ 74

    View Slide

  75. Composing "one-track" functions is easy
    def add2(n: Int): Int = n + 2
    def multi3(n: Int): Int = n * 3
    multi3(add2(10)) // 36
    val composed = (add2 _).andThen(multi3 _) // or (multi3 _).compose(add2 _)
    composed(10) // 36
    結果が分岐しない "1
    トラック"
    な関数は合成が簡単。
    75

    View Slide

  76. "Two-track" function
    However, there are many "two-track" functions in the
    real world
    def validateOrder(order: UnvalidatedOrder): Either[ValidationError, ValidatedOrder]
    def checkStock(order: ValidatedOrder): Either[OutOfStockError, AvailableOrder]
    def priceOrder(order: AvailableOrder): Either[LowerThanMinPriceError, PlacedOrder]
    しかし、現実の世界には "2
    トラック"
    な関数が多くある。
    76

    View Slide

  77. How shall we compose two-track
    functions?
    If there is an error, it should get shunted onto the
    failure track and bypass the rest of steps
    失敗時にはその先の関数をバイパスするように合成したい。どうすればよいだ
    ろうか?
    77

    View Slide

  78. That's what flatMap is for!
    そのためにあるのが flatMap

    78

    View Slide

  79. Compose two-track functions with flatMap
    def f(order: UnvalidatedOrder): Either[OrderError, PlacedOrder] =
    validateOrder(unvalidatedOrder).flatMap { validatedOrder =>
    checkStock(validatedOrder).flatMap { availableOrder =>
    priceOrder(availableOrder)
    }
    }
    flatMap
    を使って "2
    トラック"
    関数を合成する
    79

    View Slide

  80. If all of the functions go ...
    def f(order: UnvalidatedOrder): Either[OrderError, PlacedOrder] =
    validateOrder(order).flatMap { validatedOrder =>
    checkStock(validatedOrder).flatMap { availableOrder =>
    priceOrder(availableOrder) // =>
    }
    }
    すべての関数がうまくいけば...
    80

    View Slide

  81. If any function goes ...
    def f(order: UnvalidatedOrder): Either[OrderError, PlacedOrder] =
    validateOrder(order).flatMap { validatedOrder => //
    checkStock(validatedOrder).flatMap { availableOrder =>
    priceOrder(availableOrder)
    }
    }
    validateOrder
    が Left
    なら ...
    81

    View Slide

  82. If any function goes ...
    def f(order: UnvalidatedOrder): Either[OrderError, PlacedOrder] =
    validateOrder(order).flatMap { validatedOrder =>
    checkStock(validatedOrder).flatMap { availableOrder => //
    priceOrder(availableOrder)
    }
    }
    checkStock
    が Left
    なら ...
    82

    View Slide

  83. If any function goes ...
    def f(order: UnvalidatedOrder): Either[OrderError, PlacedOrder] =
    validateOrder(order).flatMap { validatedOrder =>
    checkStock(validatedOrder).flatMap { availableOrder =>
    priceOrder(availableOrder) //
    }
    }
    priceOrder
    が Left
    なら ...
    83

    View Slide

  84. for comprehension
    Is just syntactic sugar to avoid deeply nested code
    def f(order: UnvalidatedOrder): Either[OrderError, PlacedOrder] =
    for {
    validatedOrder <- validateOrder(order)
    availableOrder <- checkStock(validatedOrder)
    placedOrder <- priceOrder(availableOrder)
    } yield placedOrder
    for comprehension
    のシンタックスシュガーで深いネストを避ける
    84

    View Slide

  85. Newcomer Take: Composing Functions
    新メンバーの感想: 関数の合成
    85

    View Slide

  86. Newcomer Take: Composing Functions
    Cleans error-handling
    エラーハンドリングをきれいに書ける
    86

    View Slide

  87. Newcomer Take: Composing Functions
    Cleans error-handling
    Improves readability
    two-track functions make business logic easy to read
    ビジネスロジックが読みやすくなる
    87

    View Slide

  88. When we talk about function composition
    The key is .
    not to say the M-word
    コツは こと。
    モ○
    ドって⾔わない
    88

    View Slide

  89. When we talk about function composition
    The key is not to say the M-word.
    コツは モ○
    ドって⾔わないこと。
    89

    View Slide

  90. Patterns to support gaining
    Technology Knowledge
    テクノロジーの知識習得をサポートするパタン
    90

    View Slide

  91. "Scaffolding" in Mob/Pair programming
    Sketch out broad outlines until everyone can realize
    implementation
    Entity, Usecase, Query, Controller, routes, etc.
    ペア/
    モブプログラミングでの "Scaffolding"
    みんなが実装をイメージできるまで、⼤枠をスケッチする
    91

    View Slide

  92. Scaffolding
    Sketch a method of usecase layer.
    // in usecase layer
    def placeOrder(order: UnvalidatedOrder): Either[OrderError, PlacedOrder] = {
    // 1. validate order
    // 2. check stocks
    // 3. price order
    ???
    }
    ユースケース層のメソッドをスケッチする。
    92

    View Slide

  93. Scaffolding
    Prepare repository/query/entity method interface.
    trait StockRepository {
    /** Validate order
    * ...
    */
    def validate(order: UnvalidatedOrder): Either[InvalidOrderError, ValidatedOrder]
    }
    class JdbcStockRepository extends StockRepository {
    def validate(order: UnvalidatedOrder): Either[InvalidOrderError, ValidatedOrder] = ???
    }
    リポジトリ/
    クエリ/
    エンティティのメソッドのシグネチャを決める。
    93

    View Slide

  94. "Scaffolding" in Mob/Pair programming
    Sketch out broad outlines until everyone can realize
    implementation
    Entity, Usecase, Query, Controller, routes, etc.
    ペア/
    モブプログラミングでの "Scaffolding"
    みんなが実装をイメージできるまで、⼤枠をスケッチする。
    94

    View Slide

  95. "Scaffolding" in Mob/Pair programming
    Sketch out broad outlines until everyone can realize
    implementation
    Entity, Usecase, Query, Controller, routes, etc.
    Then check the rest of the tasks, replan, and get the
    job done individually
    Implementing a Repository/Query is a good starting point for
    newcomers
    その後に残タスクを確認して計画を修正し、個別に撃破する。
    95

    View Slide

  96. "Scaffolding" in Mob/Pair programming
    Sketch out broad outlines until everyone can realize
    implementation
    Entity, Usecase, Query, Controller, routes, etc.
    Then check the rest of the tasks, replan, and get the
    job done individually
    Implementing a Repository/Query is a good starting point for
    newcomers
    Newcomers can;
    Get technical knowledge through practice
    Reduce rework
    新メンバーは⼿戻りを減らしつつ、⼿を動かして学ぶことができる。
    96

    View Slide

  97. Newcomer's Take: Scaffolding
    新メンバーの感想: Scaffolding
    97

    View Slide

  98. Newcomer's Take: Scaffolding
    Sped up time-to-productivity
    成果を出すまでの時間を縮めることができる。
    98

    View Slide

  99. Newcomer's Take: Scaffolding
    Sped up time-to-productivity
    Spread organizational knowledge and best practices
    組織の知識やベストプラクティスを共有できる。
    99

    View Slide

  100. Newcomer's Take: Scaffolding
    Sped up time-to-productivity
    Spread organizational knowledge and best practices
    Upfront teaching costs give long-term benefits
    育成コストの前払いで、⻑期的なメリットを得る。
    100

    View Slide

  101. Introducing learning resources
    Share learning resources that dig deeper into the
    details individually
    学習リソースの紹介。
    個⼈が詳細を深掘ることができるよう学習リソースを共有する。
    101

    View Slide

  102. Introducing learning resources
    Share learning resources that dig deeper into the
    details individually
    Sometimes be sent to newcomers before they join
    the team as an preboarding process
    Preboarding
    の⼀環として、⼊社前のメンバーに送ることもある。
    102

    View Slide

  103. Some of the learning resources
    Books
    実践Scala
    ⼊⾨
    Scala Scalable Programming
    Functional Programming in Scala
    Hands-on Scala Programming
    Online Resources
    Scala
    研修テキスト
    Essential Scala
    Scala Exercises
    Essential Slick
    Scala with Cats
    S-99: Ninety-Nine Scala Problems
    Scala Pet Store Step by Step
    Play2 hands-on
    103

    View Slide

  104. Essential Scala
    Tour of syntax
    Exercises to implement generic fold,
    Equal type class, etc.
    A good read before reading FP in
    Scala
    Scala with Cats and Essential Slick
    are also recommended
    ⽂法のツアーやジェネリックなfold
    、Equal
    型クラスの実
    装。FP in Scala
    の前にやると丁度いいかも。Scala with
    Cats
    や Essential Slick
    などの姉妹編もおすすめ 104

    View Slide

  105. Scala Tutorial (Scala Exercises)
    Based on Coursera course Functional
    Programming Principles in Scala &
    Functional Program Design in Scala
    More than just how-to topics
    Side-effect and time, Functional loop, etc.
    Scala Exercises contains Typelevel's
    lib tutorials, such as Cats, Circe,
    Doobie, and so on
    Coursera
    のコースを元にしている。ただのハウツーでは
    なく、副作⽤や関数型のループなど深い内容。シリーズ
    には他にTypelevel
    のライブラリのチュートリアルも 105

    View Slide

  106. Hands-on Scala Programming
    Begins with an explanation of
    grammar, followed by some
    interesting exercises
    Sorting algorithms, file manipulation, JSON
    serialization, etc.
    In the second half, practical lessons
    creating mini-applications
    Web scraping, chatting, and real-time
    synchronization of files, etc.
    ⽂法の解説から始まり、いくつかのエクササイズが続
    く。後半はWeb
    スクレイピングや、リアルタイムファイ
    ル同期などを作る実践的な内容 106

    View Slide

  107. Play2 + Slick/ScalikeJdbc
    hands-on
    A tutorial that implements CRUD app
    with Play2 and Slick/ScalikeJdbc
    Amount that can be completed in a
    few hours to a day
    Play2 + Slick/ScalikeJdbc
    でCRUD
    アプリを作るチュート
    リアル。数時間~1
    ⽇で完了できる分量
    107

    View Slide

  108. Quick-win tasks
    A pattern that allows newcomers to contribute
    quickly
    クイックウィン タスク。新メンバーがすぐにコードにコントリビュートできる
    ようにするパタン。
    108

    View Slide

  109. Quick-win tasks
    A pattern that allows newcomers to contribute
    quickly
    Stock tasks small enough to be done in a few hours ~
    a day
    During the onboarding period, a new member's schedule is likely
    to be shredded. That's why small tasks matter
    数時間~1
    ⽇で完了するタスクを⽇頃からストックしておく。オンボーディング
    期間中はスキマ時間ができがちなので、ほどよく⼩さいサイズが⼤事
    109

    View Slide

  110. Quick-win tasks
    A pattern that allows newcomers to contribute
    quickly
    Stock tasks small enough to be done in a few hours ~
    a day
    During the onboarding period, a new member's schedule is likely
    to be shredded. That's why small tasks matter
    For example, updating dependent libraries that Scala
    Steward suggests
    例えば、Scala Steword
    が作ってくれたライブラリアップデートPull Request

    検証など。
    110

    View Slide

  111. Our practice
    in instructing
    Business Domain Knowledge
    我々が実践していること:
    ビジネスドメインの知識編
    111

    View Slide

  112. Our practice: Business Domain Knowledge
    Classroom-lectures: Market, competitors and our
    product knowledge
    座学:
    市場や競合、⾃プロダクトについての知識を得る
    112

    View Slide

  113. Our practice: Business Domain Knowledge
    Classroom-lectures: Market, competitors and our
    product knowledge
    Pair/mob programming: Product specs
    ペアプロやモブプロ: プロダクトの仕様についてのレクチャー
    113

    View Slide

  114. Our practice: Business Domain Knowledge
    Classroom-lectures: Market, competitors and our
    product knowledge
    Pair/mob programming: Product specs
    A tool: How domain knowledge is represented in
    source code
    「ドメイン知識がどのようにプロダクトで表現されているか」を可視化するツ
    ール
    114

    View Slide

  115. Zugen
    An architecture diagram generator for Scala project
    Provided as a sbt plugin
    Generates diagrams with SemanticDB/ScalaMeta
    Domain object table
    Domain relation diagram
    Method invocation diagram
    Zugen: Scala
    プロジェクトのアーキテクチャ図を⽣成するsbt
    プラグイン
    SemanticDB/ScalaMeta
    で図を⽣成する
    115

    View Slide

  116. Target source code example
    package domain.model.order
    sealed trait OrderStatus
    /** Status of an order */
    object OrderStatus {
    /** Placed Status */
    case object Placed extends OrderStatus
    /** Completed Status */
    case object Completed extends OrderStatus
    }
    /** An order */
    case class Order(
    orderId: Id[Order],
    customerId: Id[Customer],
    status: OrderStatus,
    )
    object Order {
    /** Place an order */
    def place(customerId: Id[Customer]): Order = Order(Id("1"), customerId, OrderStatus.Placed)
    }
    対象とするソースコードの例
    116

    View Slide

  117. Domain Object Table
    ドメインオブジェクトの⼀覧表
    117

    View Slide

  118. Domain Relation Diagram
    ドメインオブジェクトの関連図
    118

    View Slide

  119. Method Invocation Diagram
    メソッド呼び出し階層図
    119

    View Slide

  120. Onboarding with diagrams
    Diagrams support the understanding of how domain
    knowledge is represented in source code
    As a glossary, a map of bounded context, an overview of usecases
    図はドメインがどのようにコードで表現されているかの理解をサポートする。
    ⽤語集、概念の地図、ユースケースの概観図として。
    120

    View Slide

  121. Onboarding with diagrams
    Diagrams support the understanding of how domain
    knowledge is represented in source code
    As a glossary, a map of bounded context, an overview of usecases
    Diagrams make it easier for newcomers to join design
    discussions
    Because newcomers can see the structure, it's easier to say "this
    part can be improved"
    図で、新メンバーがデザインの議論に参加しやすくする。
    構造が⾒えるので「どこそこの形が改善できそう」など発⾔しやすくなる。
    121

    View Slide

  122. Onboarding also refines
    source code
    122

    View Slide

  123. Realizing design unfit in the onboarding
    process
    While explaining the code to newcomers, we sometimes
    feel uneasy about it
    新メンバーに既存のコードについて説明していると、たまに違和感を覚えるこ
    とがある
    123

    View Slide

  124. Realizing design unfit in the onboarding
    process
    While explaining the code to newcomers, we sometimes
    feel uneasy about it
    As the product grows, the team notices the solution
    which the team chose has become insufficient
    "Using regex to parse query params became too complicated..."
    プロダクトが育ち、過去のソリューションでは問題が解けなくなっていること
    に気づく
    124

    View Slide

  125. Realizing design unfit in the onboarding
    process
    While explaining the code to newcomers, we sometimes
    feel uneasy about it
    As the product grows, the team notices the solution
    which the team chose has become insufficient
    "Using regex to parse query params became too complicated..."
    Conversely, using "too advanced" solutions to solve
    "everyday" problems
    "Is a finite state machine necessary for this tiny usecase?"
    逆に、過度に⾼度なソリューションで⽇々の問題を解いていることに気づく
    125

    View Slide

  126. SoftwareMill Tech Blog "Simple Scala
    Stack"
    As far as Scala is concerned, it’s sometimes easy to
    lose focus on solving simple problems using
    simple code. The Scala language offers a number of
    features (...) This, in turn, can lead to complex code;
    but certainly doesn’t have to. We just need to keep
    in mind, what kind of problem are we solving


    「Scala
    では時として、シンプルな問題をシンプルに解くことへのフォーカスを
    失ってしまいがち」「どんな問題を解いているのかを⼼に留める必要がある」
    126

    View Slide

  127. Onboarding process is a great chance
    to find engineering unfit
    Turn randomness into a chance for optimization,
    reconsider styles the team had previously chosen
    オンボーディングはオーバー/
    アンダーエンジニアリングなどのunfit
    を発⾒す
    るチャンス。変化を逆⼿に取り、いままでのスタイルを⾒直す。
    127

    View Slide

  128. Not just instruction, but co-creation
    Onboarding process is not a one-way communication,
    but co-creation
    オンボーディングは⼀⽅的な伝達ではなく、共創のプロセス
    128

    View Slide

  129. Not just instruction, but co-creation
    Onboarding process is not a one-way communication,
    but co-creation
    Working together with a newcomer to find the best
    style to get 100% of the power of Scala
    Update team's awareness of the challenges
    Review the challenge-solution fit
    Scala
    の⼒を100%
    引き出すために、チームにとって最適なスタイルを新メンバ
    ーといっしょに⾒つける
    129

    View Slide

  130. Wrap up
    130

    View Slide

  131. Wrap up: Why onboarding matters
    A proper onboarding process reduces lead time to
    newcomers' maximum performance and increases
    retention rate
    This is an important issue for teams adopting Scala because of its
    learning costs
    適切なオンボーディングプロセスは新メンバーのパフォーマンスを発揮するま
    でのリードタイム短縮と離職低下に効く。これは学習コストが⾼いとされる
    Scala
    を採⽤するチームには重要な問題 131

    View Slide

  132. Wrap up: Support for gaining knowledge
    There are a lot of topics about gaining technical
    knowledge
    So narrowing the topic down from "Why do we use Scala?" is
    important
    We introduced topics we highlight and techniques
    テクノロジーの知識に関するトピックは沢⼭ある。なので「なぜ我々はScala

    使っているのか?」の問いでトピックを絞り込むことが⼤事
    132

    View Slide

  133. Wrap up: Support for gaining knowledge
    There are a lot of topics about gaining technical
    knowledge
    So narrowing the topic down from "Why do we use Scala?" is
    important
    We introduced topics we highlight and techniques
    Gaining business domain knowledge is also important
    Zugen: An architecture diagram generator for Scala project
    ビジネスドメインに関する知識も重要。理解をサポートするツールとして
    Zugen
    を紹介しました
    133

    View Slide

  134. Wrap up: Onboarding refines the code
    While using Scala, it’s sometimes easy to lose focus
    on solving simple problems using simple code. We
    need to keep in mind, what problem we are solving
    Scala
    では時として、シンプルな問題をシンプルに解くことへのフォーカスを失
    ってしまいがち。どんな問題を解いているのかを⼼に留める必要がある
    134

    View Slide

  135. Wrap up: Onboarding refines the code
    While using Scala, it’s sometimes easy to lose focus
    on solving simple problems using simple code. We
    need to keep in mind, what problem we are solving
    Onboarding process is a great chance to find
    engineering unfit
    オンボーディングは、エンジニアリングのunfit
    を⾒つける絶好のチャンス
    135

    View Slide

  136. Wrap up: Onboarding refines the code
    While using Scala, it’s sometimes easy to lose focus
    on solving simple problems using simple code. We
    need to keep in mind, what problem we are solving
    Onboarding process is a great chance to find
    engineering unfit
    In that sense, the onboarding process is not just
    instruction but actually co-creation of the best style
    to utilize 100% of the power of Scala
    その意味で、オンボーディングは⼀⽅的な伝達ではなく、Scala
    の⼒を100%

    き出すベストなスタイルを新メンバーと共に作るプロセス
    136

    View Slide

  137. Interested in HR topic like this talk?
    We're looking for Scala developers who are passionate
    about solving people's work-related challenges!
    Feel free to join our Discord channel

    私たちは⼈が働くことにまつわる課題を解決することに情熱を傾けられるScala
    開発者を探しています。まずはDiscord
    チャンネルでお話しましょう!
    137

    View Slide

  138. Thank you!
    Build a nice Scala onboarding process
    Grow your Scala team
    Make Scala community more attractive
    ありがとうございました
    素敵なオンボーディングプロセスを組み⽴てよう、Scala
    チームを育てよう、
    そしてScala
    コミュニティをさらに魅⼒的にしよう 138

    View Slide