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

6年間運用したiOSアプリの リアーキテクトについて 具体的に解説 / iOSDC 2023

6年間運用したiOSアプリの リアーキテクトについて 具体的に解説 / iOSDC 2023

https://fortee.jp/iosdc-japan-2023/proposal/bf58e5d0-a9c5-4ebb-beed-1a6c6c92de8f

kintone は、サイボウズが世界中にチームワークを広めるため開発している「業務改善プラットフォーム」のクラウドサービスです。
kintone のモバイルアプリは約6年運用してきました。
日々の開発の中で、いくつかの保守的な判断が積み重なりコードの複雑性は増していきました。
ビジネスモデルの変化やチーム構成の変化への対応に追われ、開発速度は徐々に低下していきました。
既存のプロダクトの負債とどんなやり方で向きあったのか。弊社の1ケースをありのまま紹介します。

以下の内容は取り扱いません
- リアーキテクトの技術的な詳解
- iOS開発において最高のアーキテクチャとは何か

Daiki Matsumoto

September 02, 2023
Tweet

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  7. サイボウズという会社

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  16. リアーキテクトについて

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  21. View Slide

  22. View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  44. まとめ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    時間
    保守容易性

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide