Slide 1

Slide 1 text

6年間運⽤したiOSアプリの リアーキテクトについて 具体的に解説 iOSDC 2023 松元 ⼤樹

Slide 2

Slide 2 text

6年間運⽤したiOSアプリの リアーキテクトについて 具体的に解説 iOSDC 2023 松元 ⼤樹

Slide 3

Slide 3 text

6年間運⽤したiOSアプリの リアーキテクトについて 具体的に解説 ざっくりと解説します 時間内で可能な限り具体的に話します。 詳細はブースまで

Slide 4

Slide 4 text

この話の対象者 • ⽇々の開発の中で保守容易性に課題を感じている⼈ • 他社の取り組みを知りたい⼈ 取り扱わない内容 • リアーキテクトの技術的な詳解 • iOS開発において最⾼のアーキテクチャとは何か 取り扱う内容 • 既存のプロダクトの負債とどんなやり⽅で向きあったのか。 弊社の1ケースをありのまま紹介 ↑この資料のURL

Slide 5

Slide 5 text

⾃⼰紹介 • 松元 ⼤樹(まつもと だいき) • 𝕏: daikimat • 2011年にサイボウズに⼊社 • web → モバイル、⼈材マネージャー等 • リモートワーカー • ⼦供3⼈と⾍取りや川遊びの⽇々

Slide 6

Slide 6 text

⽬次 • サイボウズ株式会社紹介 • リアーキテクトとは • リアーキテクトに⾄る経緯 • リアーキテクトの内容 • リアーキテクトによって起きた変化

Slide 7

Slide 7 text

サイボウズという会社

Slide 8

Slide 8 text

チームワークあふれる 社会を創る サイボウズの理念は「チームワークあふれる社会を創る」こと。 私たちはその理念に沿ってチームワークを⽀えるソフトウェアを 開発し続けてきました。 サイボウズという会社

Slide 9

Slide 9 text

主⼒製品 iOSアプリのコードベース運⽤歴⻑い順

Slide 10

Slide 10 text

主⼒製品 チームでのメール対応を ⼀元管理して 効率化できる メール共有システム UIKit

Slide 11

Slide 11 text

開発の知識がなくても 業務に合わせたシステムを かんたんに作成できる クラウドサービス 主⼒製品 Storyboard RxSwift SwiftUI UIKit

Slide 12

Slide 12 text

主⼒製品 スケジュール共有 ワークフローなど 中⼩企業の情報共有を ⽀援するサービス SwiftUI Combine Swift Concurrency

Slide 13

Slide 13 text

主⼒製品 管理者も現場も使いやすい 中⼤企業向けの 情報共有を ⽀援するサービス SwiftUI Combine Swift Concurrency TCA

Slide 14

Slide 14 text

サイボウズのiOSエンジニアは 4つのプロダクトを開発しています

Slide 15

Slide 15 text

開発の知識がなくても 業務に合わせたシステムを かんたんに作成できる クラウドサービス Storyboard RxSwift SwiftUI UIKit 今回の話の対象製品

Slide 16

Slide 16 text

リアーキテクトについて

Slide 17

Slide 17 text

リアーキテクトとは • リファクタリングの⼀種 • メソッドやクラスの細かいものより粒度が⼤きい • モジュールやコンポーネントレベルのもの • 外部仕様は変えないで ソースコードの設計を再設計、再構築する

Slide 18

Slide 18 text

リアーキテクトに ⾄るまで ~ kintone の場合 ~

Slide 19

Slide 19 text

リアーキテクト前の状態 • 保守容易性の低下が課題として定期的に話題に上がる • 特に新規参⼊メンバーから⾒て全体のコードの流れが把握しづらい、なぜ 動いているのかわからない • 参⼊メンバーが戦⼒になるまで時間がかかる • RxSwiftをCombine、Swift Concurrency に置き換えたいが ⾒積もれない • Strict Concurrency Check 対応 ⾒積もれない

Slide 20

Slide 20 text

リアーキ前の問題の例 • データフローとデータ⼿続がどちらもRx で表現されていて難解 • 複雑性をModelのネットワークで表現し ているのが難解→ヒエラルキーを追いか けなくてはいけない • モジュールとレイヤーが紐付いていない • 役割や命名がわかりにくい • レイヤードアーキテクチャが守られてい ない • iOS/Androidでドメイン層を共通化 →共通化⽤のコードが多い&難解 • ⼀部の機能をライブラリとして無理やり 切り出した後戻したことによって、 レイヤーと機能の⼀部が分散していて 理解に苦しむ • 密度がすごい • ゴミが多い • etc…

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

• 開発開始時(kintone v2) プロダクトの設計思想が異なるプロト タイプ(1年もの)をベースにして開発 • iOS/Androidを1チームで • ビジネスロジックを iOS/Androidで共通化 • この頃はモバイルエンジニアが5名と少なかった • 複数のサービスのモバイルアプリを担っていた • 最⼩コストで最速で作ると⾔う選択

Slide 24

Slide 24 text

• サイボウズ Office 作り直しを始める (Apache Cordova → フルネイティブ) • サーバーサイドが共通の処理の部分を ライブラリとしてゴッソリ切り出し • 切り出しに引っ張られてユーティリティな どもライブラリ側に引越し • Officeを素早く作るための選択 • 3⼈体制に突⼊ プラットフォームの変更や ライブラリアップデートで⼿⼀杯に • この頃から求⼈活動に⼒をいれる

Slide 25

Slide 25 text

• 切り出したライブラリは それぞれのプロダクトで 管理する⽅針へ (帰ってきた) • 採⽤は順調でメンバーも増えOS毎にチーム分割

Slide 26

Slide 26 text

リアーキテクトを どう進めたか

Slide 27

Slide 27 text

リアーキテクトへ挑戦1回⽬ (失敗) 考えた⼿順 1. 現状をしっかりと把握する(テストコードも) 2. 1を踏まえて、理想となる形を議論して決める 3. 2の「理想となる形に向けてのロードマップ」を決める 4. 3のロードマップに沿ってリアーキテクトを進めていく

Slide 28

Slide 28 text

1.現状をしっかりと把握する 新規参⼊メンバー 把握できないから困っとるんじゃ 既存メンバー 現状の問題が⾮常に多い ⾔語化が難しい 何から⼿をつけるべきなのか 優先度をつけれない

Slide 29

Slide 29 text

リアーキ前の問題の例 • データフローとデータ⼿続がどちらもRx で表現されていて難解 • 複雑性をModelのネットワークで表現し ているのが難解→ヒエラルキーを追いか けなくてはいけない • モジュールとレイヤーが紐付いていない • 役割や命名がわかりにくい • レイヤードアーキテクチャが守られてい ない • iOS/Androidでドメイン層を共通化 →共通化⽤のコードが多い&難解 • ⼀部の機能をライブラリとして無理やり 切り出した後戻したことによって、 レイヤーと機能の⼀部が分散していて 理解に苦しむ • 密度がすごい • ゴミが多い • etc…

Slide 30

Slide 30 text

現状把握を踏まえて、 2.理想となる形を議論して決める 理想のアーキテクチャをすぐには決められない問題が発⽣ • プロダクトが提供している価値や要素は何があるのか把握して⾔語化したい • ⼀般的なアーキテクチャパターンについて学習してから挑みたい • 機能開発とめて集中してこれについて考えたい ステークホルダーを説得せねば などといっている間にリアーキテクト保留状態へ

Slide 31

Slide 31 text

リアーキテクトへ挑戦2回⽬ しばらくして、 チームの構成が変わり(iOS/Androidをチーム分離) チーム外の有識者を交えて再度考えた⼿順 1. ⼩さな単位(モジュール)に分割する 2. 分割した単位ごとに改善を⾏う 3. 1 or 2をひたすら繰り返す

Slide 32

Slide 32 text

分割リアーキテクト メリット • 作業のスコープが⼩さくなりリスクをコントロールし やすい • 遅延・作業中の外部環境変化に柔軟に対応できる • ⾒積もりがしやすい • 影響範囲が限定される • 理想的なアーキテクチャや その実装イメージが明確でなくても作業を進めること ができる • 機能開発と並⾏してリアーキテクト活動ができる

Slide 33

Slide 33 text

開発フローとの相性良し スクラムフレームワーク

Slide 34

Slide 34 text

分割リアーキテクト デメリット • 分割ポイントを探るのが難しい • 結果的には末端の分割可能な画⾯や機能単位で分割した • コード全体での⼀貫性は考えづらい

Slide 35

Slide 35 text

初めの1歩⽬について • 開発時にしか使わないデバッグ⽤の画⾯を分割 • 絶対に顧客環境には提供されないため 外部仕様に影響がないし、独⽴性も⾼いはず と思って⾃信を持って始めた • ⼿を動かすことによって分割することが ⾮常に難しい状態になっていると気づく • やりたい施策がたくさん⾒つかったのでタスク化 • タスク化→作業する→タスク化→ のリズムができて軌道に乗れた

Slide 36

Slide 36 text

タスクになったものの例 • DIやLogicがViewの状態に依存している • 共有される UIコンポーネント、ドメインロジック、 Utilityなどが散らばっている • 1つのコンテキストに関連するコードの範囲が巨⼤ • モジュール同⼠の依存関係、ライブラリ依存の範囲がわかりにくい → 課題を解決してから モジュール化

Slide 37

Slide 37 text

ADRを⽤意して記載する Title アーキテクチャ決定(決断)の簡単な説明 Context この決定(決断)または変更の動機となっている問題は何ですか? Decision 私たちが提案している、または⾏っている変更は何ですか? Consequences この変更により、どのようなことがより 簡単になったり、より難しくなったりしますか? シンプルな ADR template by Michael Nygard を採⽤ (Architecture Decision Record)

Slide 38

Slide 38 text

ADRメリット •同じ議論を何度もしない、 決定の経緯を辿れる •書く場所があることで リアーキテクト活動に誰でも参加できる

Slide 39

Slide 39 text

リアーキテクトタスクをいつ作るか 1⽇45分の予定を確保 • 元々バックログのリファイメントに使っていた時間を流⽤ • 基本はリファイメントを⾏う • リファイメントが無い⽇や、リファイメント後に余った時間は リアーキテクト検討に利⽤して、定期的にリアーキテクトについて話す 何をするか • 現状の課題、今後の⾒通しについて議論 • 次に着⼿できそうなところ、改善案をADRで記録 & 議論 • 数時間〜数⽇で実施できる範囲の作業をバックログ化

Slide 40

Slide 40 text

機能開発と リアーキテクトタスクの優先順位 • 機能開発との優先順位はPMとQAと都度相談して決める (通常のスクラムイベントのスプリントプランニングのこと) • 結果的には投⼊⽐率 5:5 くらいで 投資されている • kintoneの場合、プロダクトの開発⽅針として 中⻑期的に価値提供するための改善活動の優先度は⾼い

Slide 41

Slide 41 text

リアーキテクトによって 起きた変化

Slide 42

Slide 42 text

認知負荷が下がった • 特定のコンテキストで分離されることで認知負荷が減少 • コンテキストの⼀覧と依存関係を把握可能に • 本質的には不要なコードの発⾒と削除 • Androidとビジネスロジックを共通化するためのコード • 設計思想の異なる時代の設計を実現するためのコード • DIコンテナ保持のためのView • 他にも⾊々..

Slide 43

Slide 43 text

新技術導⼊や Swiftバージョン追従への⾒通しの変化 • モジュール単位なら導⼊の敷居は⾮常に下がった • Strict Concurrency Check • RxSwift → Swift Concurrency • Storyboard → SwiftUI • また業務で利⽤できることによって新技術を実プロ ダクトで⼿を動かしながら学ぶことができるように

Slide 44

Slide 44 text

まとめ

Slide 45

Slide 45 text

まとめ • モバイルアプリ開発は取り巻く環境の変化と切り離せない • ビジネスの中でのモバイルアプリの⽴ち位置の変化 • チーム構成の変化 • 保守的な判断によって認知負荷が⾼いコードになり得る • 我々は全体リライトを検討したが挫折、 ⼩さく分割する⽅針のリアーキテクトを始めた • 分割によるマルチモジュール化は巨⼤な何かと向き合うのに相性が良かった • 初めの1歩を踏み出す事は偉⼤ やってみるとちゃんと進んだ 理解が進む、技術継承が進む、コード品質改善が進む

Slide 46

Slide 46 text

最後までご覧いただき ありがとうございました🙏 サイボウズについて詳しく知りたい⽅、 今回の話のより詳細を聞きたい⽅、 リアーキテクト談義をしたい⽅、 雑談したい⽅ブースまでお越しください! 採⽤サイトもご覧ください! https://cybozu.co.jp/recruit/

Slide 47

Slide 47 text

2023年9⽉26⽇(⽕)19:00 開始 オンライン開催!申し込みページは↓↑ https://hey.connpass.com/event/290854/

Slide 48

Slide 48 text

おまけ (⼊りきらなかったやつ)

Slide 49

Slide 49 text

元のアーキテクチャ MVVMとVIPPERのRouterを組み合わせたようなもの DomainレイヤーはiOS/Androidで全く同じものをSwift/Kotlinで記述する

Slide 50

Slide 50 text

現在進⾏形のアーキテクチャの状況 • ⼀つ⼀つのモジュール内は 深く考えられていない • ⼩さいモジュールの依存関係 を整理し、モジュール分割単 位や、依存関係など試⾏錯誤 を繰り返している段階 • 理想は依存関係がフラットで 依存モジュールが少ない状態 を⽬指すがなかなか難しい…

Slide 51

Slide 51 text

保守容易性の下がり⽅ • ⽇々技術的負債を返却する活 動は⾏っていたものの、 保守容易性は徐々に低下した • 始めたばかりのプロダクトの 保守容易性はめちゃくちゃ⾼ い 時間 保守容易性

Slide 52

Slide 52 text

なぜ保守容易性が 下がったのか • ビジネスの中でのモバイルアプリの⽴ち位置の変化 • チーム構成の変化 これらに対し保守的な判断を積み重ねた なぜ?🤔 • 課題を⾒直すには全体リライトするしか発想がなく、 莫⼤な⼯数がかかるものだと思って避けていた • 素早く価値を届けることを優先 • 組織として体制が弱く余裕がなかった

Slide 53

Slide 53 text

リアーキテクトに踏み切れた 理由① • モバイル職能のエンジニアが増えて体制が強くなっていた • チームメンバーが替わることで現状のコードの理解難易度の⾼さを認識した • iOS/Androidのビジネスロジックを揃える制約を外し、 ⼩さい別チームにしたことで⾃由度が上がり動きやすくなった • kintoneとして「プロダクトを⻑期的に継続提供するための投資」を重点領域の1つとし ているが、これはモバイルアプリも同様であることに気づいた

Slide 54

Slide 54 text

リアーキテクトに踏み切れた 理由② • 後発で作成したアプリとの設計差を感じるようになった • モダンな技術の取り込みが採⽤に響くことも実感 • 後発で作成したアプリで知⾒が溜まっていた • サイボウズOfficeの設計、⼀般的なアーキテクチャについての有識者を 必要に応じて派遣してもらう同盟を結んだ • ADR(Architecture Decision Record)を作成してアーキテクチャについて ⼩さく進められる場を作った

Slide 55

Slide 55 text

モジュールをどこで切るか • モジュールの分け⽅で 「レイヤー」 or 「境界付けられたコンテキスト」の選択肢があった • 今回採⽤した分割⽅針は「境界付けられたコンテキスト」 • 各モジュール内で必要に応じて適切なレイヤー分けをする • 共通系のモジュールが⽣まれる場合は、各モジュール内で完結でき ないか、 モジュールの分け⽅として最適だったのかを検討する

Slide 56

Slide 56 text

その他細かい話 • 作業を通じて曖昧だった依存関係が分かるため技術継承が進む • 中⻑期的に⾮常に有益なのでリアーキテクトは定期的に⾏う ⽅が良いと考えるようになった • ⼩さいモジュールごとにテストが書きやすい • 各モジュールのビルドが通れば、 そこはちゃんとしていると安⼼できる