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. § 濵田 健 / Ken Hamada (id:itchyny) § 2021/11 サイボウズ入社

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

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

    オーナーシップ意識 クロスファンクショナル 機能毎にパッケージ分割 レビューコスト 大規模リファクタリング 開発の加速 開発体制の改革 組織面 プロジェクト制 技術面
  4. kintone開発チームの職種 プロダクト マネージャー (PdM) デザイナー リサーチャー テクニカルライター ローカライズ エンジニア (PG)

    QAエンジニア アクセシビリティ スクラムマスター 約90名の様々な職種のメンバーが所属
  5. 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
  6. ∎PdMがバックログを作成 § リファインメントでPBI共有、見積もり、優先順位付け ∎サブチームにPBIを割り振り § PG 3〜4人 + QA(兼務あり)のサブチーム ×

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

    消化したストーリーポイントを kintoneに記録してグラフ描画
  8. ∎マイクロサービス化の検証プロジェクト (2021/6-10) § 分離しやすそうな機能を一つ切り出す検証(組織・技術) § 認証・通知・DB分離・トランザクション・E2Eテストなど ∎検証プロジェクトの結果 § 分離しやすそうな機能だったが他の機能と密結合だった §

    分離しやすそうな機能は開発の優先度もモチベも低い § 分離する工数、整合性担保など技術的困難もあり断念 § 小さいチームの意思決定の速さ・職種間の連携が密に マイクロサービス化の検討
  9. ∎フィーチャーチーム § 担当領域 (機能) を明確化して、認知負荷を下げる § アプリ設定チームを発足 (2022/6-) ∎クロスファンクショナル §

    各職種のメンバー・密にコミュニケーション ∎逆コンウェイ戦略 § チームの形 → システムアーキテクチャーの形 § チーム間のインタラクションモードを意識 領域専任のチーム体制へ
  10. 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
  11. チーム体制の未来図 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基盤チーム
  12. アジェンダ 意思決定コスト 認知負荷 逆コンウェイ戦略 領域専任チーム 探求時間 個人改善 自律的改善チーム 属人性の低減 モノリス

    オーナーシップ意識 クロスファンクショナル 機能毎にパッケージ分割 レビューコスト 大規模リファクタリング 開発の加速 開発体制の改革 組織面 プロジェクト制 技術面
  13. ∎JUnit:Javaのユニットテストのフレームワーク § JUnit 5は2017/9 Release → 時は流れ… ∎2022年になっても、JUnit 4を使っていた §

    テスト用なのでアップデートの必要性は? § 移行する工数とプロダクトの価値提供は? § 一万クラスのテストを書き換える手段は? § 並列実行の仕組みの移行方法は? JUnit 5へのアップデート
  14. 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で徐々に移行も可能だが 混在すると認知負荷が上がるので一気に移行
  15. ∎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” で検索 🔍
  16. ∎Joda-Time:Javaで日時を扱うライブラリ (2005-) § Java 8のJSR-310 Date and Time APIへの移行を推奨 §

    SpringのJoda-Timeインテグレーションも非推奨 § 移行を怠っているとライブラリ更新できなくなる危機 ∎全製品で移行を決定、プロジェクト化 § 週に三時間ほど集まり、機能ごとに移行 § IntelliJ IDEAのType migrationが便利 Joda-TimeからJSR-310への移行 おつかれさまでした!
  17. 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"): 小数点時の秒以下
  18. 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 (月末日)
  19. タイムゾーンの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
  20. 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): 夏に時計を進める
  21. 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
  22. 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
  23. ∎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
  24. 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準拠の継承方法 メソッドの定義も 呼び出しも完結 読むのもつらいし書くのも楽しくない
  25. ∎IDEの機能 § IntelliJ IDEAの構造検索と置換 ∎semgrep § OCaml製・各種言語に対応 ∎sed・awk・(git-)grep・Perl・IdeaVim § "/pattern1/{:l;

    /pattern2/!{N; bl}; ...}" "/.../{F; p}" ∎自前で実装 リファクタリングに使うツール 構文木・厳格・特化 行毎・寛容・汎用 厳格さをコントロール・実装コスト高 属人性高・メンテナンス難・特化型 インスペクションに設定可能 Vimのマクロも対応!
  26. まとめ 意思決定コスト 認知負荷 逆コンウェイ戦略 領域専任チーム 探求時間 個人改善 自律的改善チーム 属人性の低減 モノリス

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