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

組織と技術の両輪で開発を加速させるkintoneチームの取り組み / JJUG CCC 2022 Fall Cybozu kintone

Ken Hamada
November 27, 2022

組織と技術の両輪で開発を加速させるkintoneチームの取り組み / JJUG CCC 2022 Fall Cybozu kintone

kintoneは2011年のリリース以降、開発チームが90名になるまで成長し、コードベースも肥大化を続けてきました。しかし、組織もコードベースもモノリシックなまま成長を続けてきたため、メンバーの認知負荷やコミュニケーションコストの増大などによって、開発体制がスケールしない問題を抱えていました。今後、開発を加速かつスケールさせるために、領域専任のチーム体制への移行に挑戦しています。技術面でも、開発を加速するための改善に取り組むプロジェクトを、エンジニアが起案し、チームを発足して進められるようになりました。JUnit 5へのアップデートや、Joda-TimeからJSR-310 Date and Time APIへの移行、さらにフロントエンドのクラス構文への移行など、多岐に渡る改善プロジェクトが進行しています。組織面と技術面の両輪で開発を加速するための取り組みについてお話しします。

Ken Hamada

November 27, 2022
Tweet

More Decks by Ken Hamada

Other Decks in Programming

Transcript

  1. 組織と技術の両輪で開発を加速させる kintoneチームの取り組み JJUG CCC 2022 Fall Nov 27, 2022 濵田

  2. § 濵田 健 / Ken Hamada (id:itchyny) § 2021/11 サイボウズ入社

    § kintone開発チーム/ソフトウェアエンジニア § Java/TypeScript/Go/Rust/Haskell/Vim/jq § lightline.vim/gojq/bed/json2yaml (in Go) 自己紹介
  3. 業 務 シ ステ ム を 簡単 に 作成 ス

    ム ー ズな デ ー タ共 有 プ ロ セ ス管 理 ・ アク セ ス権 限 コ ミ ュ ニケ ー シ ョン 基 盤 国 内 2 5 , 5 0 0 社 ( 2 0 2 2 年 8 月 末 ) kintone
  4. アジェンダ 意思決定コスト 認知負荷 逆コンウェイ戦略 領域専任チーム 探求時間 個人改善 自律的改善チーム 属人性の低減 モノリス

    オーナーシップ意識 クロスファンクショナル 機能毎にパッケージ分割 レビューコスト 大規模リファクタリング 開発の加速 開発体制の改革 組織面 プロジェクト制 技術面
  5. 開発体制の改革 〜領域専任のチーム体制へ〜

  6. kintone開発チームの職種 プロダクト マネージャー (PdM) デザイナー リサーチャー テクニカルライター ローカライズ エンジニア (PG)

    QAエンジニア アクセシビリティ スクラムマスター 約90名の様々な職種のメンバーが所属
  7. kintone開発チームの体制 PdM PdM PdM プロダクト バックログ サブチームA PG PG PG

    QA QA デザイナー デザイナー デザイナー ライター ライター ローカ ライズ ローカ ライズ スプリント プランニング レビュー ソースコード 全体振り返り 新規開発チーム React移行チーム DXチーム メンテチーム モバイルチーム AWS基盤チーム サブチームB PG PG PG QA QA サブチームC PG PG PG QA QA サブチームD PG PG PG QA QA
  8. ∎PdMがバックログを作成 § リファインメントでPBI共有、見積もり、優先順位付け ∎サブチームにPBIを割り振り § PG 3〜4人 + QA(兼務あり)のサブチーム ×

    3〜4 § デイリースクラム、モブプログラミング、振り返り ∎スプリントレビュー、全体振り返り § 1スプリント 1週間 スクラム開発 (LeSS) Large-Scale Scrum
  9. 2021年 ごろ から 開 発速 度 が顕 著に 低下 開発速度の低下

    消化したストーリーポイントを kintoneに記録してグラフ描画
  10. ∎PdM・デザイナー・ライターはサブチームに所属しない § サブチームのデイリースクラムや振り返りにも不参加 § コミュニケーションコストが高い・心理的な距離感 ∎バックログ担当箇所が決まっていない § 実装箇所、見積もりの不確実性が高い ∎認知負荷が高い・オーナーシップ意識が希薄 チーム体制のモノリス性

  11. ∎モノリシックなアーキテクチャー・リポジトリ § サーバーサイド・フロントエンド共に § 一部は別リポジトリでパッケージ化(更新頻度低) § コードベースは肥大化、依存関係が複雑化 § 変更の影響範囲が広く、学習コストが高い §

    新しいメンバーの育成に時間がかかる ∎認知負荷が高い・オーナーシップ意識が希薄 アーキテクチャーのモノリス性
  12. ∎マイクロサービス化の検証プロジェクト (2021/6-10) § 分離しやすそうな機能を一つ切り出す検証(組織・技術) § 認証・通知・DB分離・トランザクション・E2Eテストなど ∎検証プロジェクトの結果 § 分離しやすそうな機能だったが他の機能と密結合だった §

    分離しやすそうな機能は開発の優先度もモチベも低い § 分離する工数、整合性担保など技術的困難もあり断念 § 小さいチームの意思決定の速さ・職種間の連携が密に マイクロサービス化の検討
  13. 『チームトポロジー: 価値あるソフトウェアを すばやく届ける適応型組織設計』 チームタイプと チーム間のインタラクションモードの分類 自チームが他のチームとどう関わるべきか ʰνʔϜτϙϩδʔʱษڧձ https://pub.jmam.co.jp/book/b593881.html

  14. ∎フィーチャーチーム § 担当領域 (機能) を明確化して、認知負荷を下げる § アプリ設定チームを発足 (2022/6-) ∎クロスファンクショナル §

    各職種のメンバー・密にコミュニケーション ∎逆コンウェイ戦略 § チームの形 → システムアーキテクチャーの形 § チーム間のインタラクションモードを意識 領域専任のチーム体制へ
  15. PG QA デザイナー ローカ ライズ スクラム イベント 領域Aチーム PdM PG

    ライター PBL 領域専任チームの発足 PdM PdM PdM プロダクト バックログ デザイナー デザイナー ライター ローカ ライズ 新規開発チーム ソースコード 全体振り返り スクラム イベント React移行チーム DXチーム メンテチーム モバイルチーム AWS基盤チーム サブチームA PG PG PG QA QA サブチームB PG PG PG QA QA サブチームC PG PG PG QA QA
  16. チーム体制の未来図 PdM 新規開発チーム PG QA デザイナー ローカ ライズ スクラム イベント

    領域Dチーム PdM PG ライター PBL PG QA デザイナー ローカ ライズ スクラム イベント 領域Cチーム PdM PG ライター PBL PG QA デザイナー ローカ ライズ スクラム イベント 領域Bチーム PdM PG ライター PBL PG QA デザイナー ローカ ライズ スクラム イベント 領域Aチーム PdM PG ライター PBL ソースコード・全体振り返り React移行チーム DXチーム メンテチーム モバイルチーム AWS基盤チーム
  17. ∎巨大でモノリシックなコードがここにあるんだが? § 逆コンウェイ戦略はすでにあるモノリスシステムには? ∎パッケージの分割:リスクもコストも低い § サーバーサイド・フロントエンド共に機能ごとに分割中 § ArchUnitで依存関係をテスト・Gradle multi-project化 §

    依存関係をグラフ描画 → 変な依存は随時解消 § オーナーシップの明確化・認知負荷の低減 機能毎のパッケージ分割
  18. ∎領域専任のチーム体制へ移行に挑戦中 § 担当する領域(機能)を明確化 § 各職種が所属する小さなチームで自律性を向上 § 新規開発の活発なコアドメインから分割 ∎機能毎にパッケージを分割(モジュラーモノリスへ) § 依存関係を描画、修正、テスト

    → 境界と依存の統制 § Gradle multi-project化 ∎認知負荷、学習コストやモノリス性の低減 開発体制の改革(まとめ)
  19. アジェンダ 意思決定コスト 認知負荷 逆コンウェイ戦略 領域専任チーム 探求時間 個人改善 自律的改善チーム 属人性の低減 モノリス

    オーナーシップ意識 クロスファンクショナル 機能毎にパッケージ分割 レビューコスト 大規模リファクタリング 開発の加速 開発体制の改革 組織面 プロジェクト制 技術面
  20. プロジェクト制の発足 〜PG主導の改善プロジェクト〜

  21. ∎探求時間:バックログの開発以外に各自で「探求」 § リファクタリングなどの改善や個人学習など ∎一人で大きな改善を進めるのはつらい § その改善はいつ終わるの? § 見積もりの欠如、属人性が高い、停止判断を下す立場の不在 § レビューする側も大変

    § 改善の背景の理解に時間がかかる § 工数を割く価値がPdMに伝わっていない 探求時間
  22. ∎プロジェクト制 (2022/1-) § 大きな改善やプロトタイピングを実施する枠組み § 目的やゴール、期限をチーム運営に説明して承認 § プロジェクト憲章のテンプレートがある § プロジェクトマネージャー・メンバー・スポンサー

    § スポンサー:プロジェクトの外から助言や停止判断を行う プロジェクト制の発足
  23. § JUnit 5へのアップデート § Joda-TimeからJSR-310への移行 § フロントエンドの改善 § 他多数 実施されたプロジェクト

    PGの改善が 活発に!
  24. JUnit 5へのアップデート

  25. ∎JUnit:Javaのユニットテストのフレームワーク § JUnit 5は2017/9 Release → 時は流れ… ∎2022年になっても、JUnit 4を使っていた §

    テスト用なのでアップデートの必要性は? § 移行する工数とプロダクトの価値提供は? § 一万クラスのテストを書き換える手段は? § 並列実行の仕組みの移行方法は? JUnit 5へのアップデート
  26. JUnit 5へのアップデート JUnit 4 JUnit 5 org.junit.Test org.junit.jupiter.api.Test @Before @BeforeEach

    @After @AfterEach @BeforeClass @BeforeAll @AfterClass @AfterAll @Ignore @Disabled @Theory @ParameterizedTest @Enclosed @Nested 置換してgit commitするスクリプトを準備 junit-vintage-engineで徐々に移行も可能だが 混在すると認知負荷が上がるので一気に移行
  27. ∎Maven Surefire Plugin の parallel=classes § runOrder=balanced でCI時間を短縮していた ∎JUnit 5.3から並列実行をサポート

    § junit.jupiter.execution.parallel.enabled=true § 並び替えは ClassOrderer を独自に実装 § 前回の実行時間のログを使い、遅いテストクラスから実行 JUnitテストの並列実行 並列実行とクラス並び替えの組み合わせで意図しない順序になるバグがある → The order of classes is not correct when parallel execution is enabled 詳しくは “kintone JUnit 5” で検索 🔍
  28. Joda-TimeからJSR-310への移行

  29. ∎Joda-Time:Javaで日時を扱うライブラリ (2005-) § Java 8のJSR-310 Date and Time APIへの移行を推奨 §

    SpringのJoda-Timeインテグレーションも非推奨 § 移行を怠っているとライブラリ更新できなくなる危機 ∎全製品で移行を決定、プロジェクト化 § 週に三時間ほど集まり、機能ごとに移行 § IntelliJ IDEAのType migrationが便利 Joda-TimeからJSR-310への移行 おつかれさまでした!
  30. Joda-Timeがパースできるもの § LocalDate.parse("12345-1-1"): 五桁年、0埋めなし § DateTime.parse("2022T10"): 年と時のみ § DateTime.parse("2022-03-04T"): Tあり時刻なし

    § LocalTime.parse("T12:13:14"): Tから始まる時刻 § LocalTime.parse("12:13:14,567"): 小数点が "," § LocalTime.parse("3.5555"): 小数点時の秒以下
  31. JSR-310での日時のフォーマット ∎DateTimeFormatter.ofPatternが基本 § 西暦年はy (year-of-era) ではなくu (year) § yyyy は西暦0年が

    "1" に、紀元前の年に "-" がつかない § "令和4年" をパースする時はGGGGy (JapaneseChronology) § uuuuは10000年以上に "+" がつく (SignStyle.EXCEEDS_PAD) ∎DateTimeFormatterBuilder § パース時は ResolverStyle.STRICT を指定 § デフォルトはSMART: 11/31 → 11/30 (月末日)
  32. タイムゾーンのformatterの違い output Joda-Time JSR-310 +0900 Z Z, xx +09:00 ZZ

    xxx +09 -- x JST z z Asia/Tokyo ZZZ VV Japan Standard Time zzzz zzzz GMT+09:00 -- ZZZZ, OOOO
  33. Joda-TimeとJSR-310の夏時間 リマインダーの条件通知 Joda-Time JSR-310 org.joda.time.DateTimeZone java.time.zone.ZoneRules (java.time.ZoneId#getRules) isStandardOffset(long) isDaylightSavings(Instant) previousTransition(long)

    previousTransition(Instant) nextTransition(long) nextTransition(Instant) 夏時間と標準時の切り替わるぴったりの日時に注意 夏時間 (daylight saving time): 夏に時計を進める
  34. Joda-TimeとJSR-310の夏時間 > var dt = OffsetDateTime.parse("2022-11-06T09:00:00Z"); > Instant.ofEpochMilli( org.joda.time.DateTimeZone.forID("America/Los_Angeles") .previousTransition(dt.toInstant().toEpochMilli()));

    2022-11-06T08:59:59.999Z > java.time.ZoneId.of("America/Los_Angeles").getRules() .previousTransition(dt.toInstant()).getInstant(); 2022-03-13T10:00:00Z
  35. Joda-TimeとJSR-310の夏時間 > var dt = OffsetDateTime.parse("2022-11-27T09:00:00Z"); > Instant.ofEpochMilli( org.joda.time.DateTimeZone.forID("America/Los_Angeles") .previousTransition(dt.toInstant().toEpochMilli()));

    2022-11-06T08:59:59.999Z > java.time.ZoneId.of("America/Los_Angeles").getRules() .previousTransition(dt.toInstant()).getInstant(); 2022-11-06T09:00:00Z
  36. フロントエンドの改善

  37. ∎Google Closure Tools § Google製・2009/11- § AngularJS 2010/10, TypeScript 2012/10,

    React 2013/05, Vue.js 2014/02 § JavaScriptトランスパイラ・ライブラリ群 § 変数名やクラスのフィールド名をminify § テンプレートエンジン・型システム Google Closure Tools https://developers.google.com/closure/library
  38. ∎Google Closure Toolsを採用 § 2009年末のフレームワーク選定により採用決定 § 社内の他製品ではjQueryとYUIを使っていた § 豊富なライブラリ群・DOM操作・イベントハンドリング ∎現在、JavaScript・テンプレート含め50万行以上

    § フロントエンドエコシステムの潮流から乖離 § Google Closure Toolsに詳しい人が少ない、採用難 kintoneのフロントエンド
  39. フロントエンドの刷新 ∎全てのページをReact化するプロジェクト § フロントエンドをリアーキテクチャするプロジェクト § 技術的にもチーム的にも分割し、スケールできる § クロスファンクショナルで自律性のある四つのチーム § フロントエンドのモノリスからの脱却

    § 詳しくは “kintone フロリア” で検索🔍
  40. ∎既存のコードでの機能開発は継続中 § 現状はReact移行チームの機能実装が後追い ∎機能開発の速度を維持・改善するために § 不要な実装を削除する (IE対応など) § 古い記法を新しくする §

    prototype記法のclass構文移行 § React移行の際にも読みやすさは重要 既存のフロントエンドの改善
  41. prototype記法のclass構文移行 var SampleComponent = function(items) { SampleComponent.base(this, 'constructor'); this.items_ =

    items; }; goog.inherits(SampleComponent, Component); SampleComponent.prototype.getItems = function () { return this.items_; }; SampleComponent.prototype.disposeInternal = function () { SampleComponent.base(this, 'disposeInternal'); }; class SampleComponent extends Component { constructor(items) { super(); this.items_ = items; } getItems() { return this.items_; } disposeInternal() { super.disposeInternal(); } } closure library独自の継承方法 メソッドの定義が冗長 基底クラスのメソッドを呼ぶのも長い ES2015準拠の継承方法 メソッドの定義も 呼び出しも完結 読むのもつらいし書くのも楽しくない
  42. ∎RubyスクリプトでJavaScriptのコードを変換 § 3時間で実装した200行程度のRubyスクリプト § 関数やメンバーの定義ごとにテキスト処理(構文木ではない) § 自動変換できないコードは先に手で修正から変換 § super(); の前に

    this にアクセスしているなど ∎プロジェクトをPGが提案し、現在も進行中 § 1000クラス以上が移行完了 prototype記法のclass構文移行
  43. ∎IDEの機能 § IntelliJ IDEAの構造検索と置換 ∎semgrep § OCaml製・各種言語に対応 ∎sed・awk・(git-)grep・Perl・IdeaVim § "/pattern1/{:l;

    /pattern2/!{N; bl}; ...}" "/.../{F; p}" ∎自前で実装 リファクタリングに使うツール 構文木・厳格・特化 行毎・寛容・汎用 厳格さをコントロール・実装コスト高 属人性高・メンテナンス難・特化型 インスペクションに設定可能 Vimのマクロも対応!
  44. ∎不要な実装や記法の混在を放置しない § 「このコードは使われていないので消すと良さそう」 § 「Javaの新しい記法を使うと良さそう」 § これらの放置は開発時の生産性の低下につながる ∎一人での改善は本人もレビュアーもチームもつらい § プロジェクト制、コード品質の改善を草の根活動に頼らない

    § 責任者を明確化、不確実性・属人性を低減、QAと連携 § 場面に応じた手法で大規模にリファクタリング 「〜すると良さそう」を「やる」には
  45. まとめ 意思決定コスト 認知負荷 逆コンウェイ戦略 領域専任チーム 探求時間 個人改善 自律的改善チーム 属人性の低減 モノリス

    オーナーシップ意識 クロスファンクショナル 機能毎にパッケージ分割 レビューコスト 大規模リファクタリング 開発の加速 開発体制の改革 組織面 プロジェクト制 技術面
  46. We are Hiring! kintone 採用情報 🔍