Chatwork Creator's Note

ビジネスチャット「Chatwork」のエンジニアとデザイナーのブログです。

ビジネスチャット「Chatwork」のエンジニアとデザイナーのブログです。

読者になる

SVVSの裏話〜リアーキテクチャと組織体制

モバイルアプリケーション開発部のiOS担当の方の池田(Twitter: m_ike)です。

2023年のiOSDCで、SVVSという新アーキテクチャ導入についてスポンサーセッションで弊社から発表させていただきました(資料はこちら)。 この記事では、そもそもなぜ独自のアーキテクチャを採用するに至ったのか?という裏側について公開します。

Chatworkのアプリでは、発表の中であったとおり技術的負債が課題となっておりリアーキテクチャを検討する流れとなっていました。しかし、リアーキテクチャはかなりのリスクとチャレンジが伴うものです。Chatworkのアプリは画面数でいうとViewControllerベースで120以上あるため結構な工数と期間がかかるだけでなく、採用した新しいアーキテクチャがうまくなじまず導入に失敗する可能性もあります。 実際、過去にもリアーキテクチャを試したものの局所的な改修に留まってしまい、画面や実装時期によってアーキテクチャが異なるという結果*1になってしまっています。

私自身、リアーキテクチャは必要で進めたいと口で言いつつも、実際には現実的でないと考えていて新規実装やリファクタリングで徐々にアーキテクチャを統一した方がまだ成功する可能性が高いと思っていました。そういった感じでリアーキテクチャに慎重というか懐疑的だったわけですが、組織体制の変更をきっかけ*2に一気にリアーキテクチャ推進派へと舵を切りました。

コンウェイの法則と組織体制の変更

鍵となるのは、「コンウェイの法則」です。これを元にした逆コンウェイ戦略に沿って、開発生産性の向上を目指しフィーチャーチーム化が進められることになりました。(詳しくはこちらの資料を参照ください)

iOSチームでいうと、大きく分けてプラットフォームチームとフィーチャーチームに分離されることとなりました。 プラットフォームチームがアーキテクチャや共通機能、開発環境などの基盤を整備し、それをフィーチャーチームが活用して高速な開発を目指す体制です。

コンウェイの法則では、「アーキテクチャは組織体制とよく似たものになっていく」と言われています。 実際、iOSチームはそれまで社歴の長いベテランメンバーが多く比較的モノリスなチームであったため、アプリ自体もモノリスな構造になっていました。 例えば、GodなManagerクラスが存在していたり、依存関係が複雑でマルチモジュール化できないような作りであったり、テクニカルなコードで実装されたりしていました。 ある程度のスキルとドメイン知識が身についてくると、あぁなるほど!となって効率よく開発できるのですが、かなり初見殺しのコードでした。

しかし、フィーチャーチーム化によってこれまでとは違ったメンバーがコードを触る機会が増えることになりました。 フィーチャーチームではチーム内で開発を完結させるため、普段サーバメインの人がモバイルを実装するケースもあります。もちろん、実装にあたってはプラットフォームチームの技術的な支援(レビューやモブプロなど)はあるのですが、やはりコミュニケーションコストやリードタイムを考えるとフィーチャーチームで実装を完結できた方が良くなります。 それで、現行のアーキテクチャと開発体制の「ねじれ」を解消するには、各チームで完結しやすくシンプルでわかりやすいアーキテクチャが必要となってきたわけです。

SVVSとフィーチャーチーム

そういった経緯で、今後のアーキテクチャをどうするかを検討して生まれた*3のが、SVVSです。 検討時だと世間ではTCAの評価が高かったりしましたが学習コストや複雑さの面から採用を見送り、既存のアーキテクチャの良いところを取り入れてシンプルさを追求した結果、独自のアーキテクチャになりました。

例えば、レイヤー自体もチーム体制を意識したものとなっています。SVVSはMVVMとよく似ており、データソースとなる「Store」と画面である「View」、そしてそれを繋ぎViewの状態を管理する「ViewState」からなります。

Viewは、フィーチャーチームが担当する場所、自由に触ってよい部分です。ただし、開発の効率化とアプリ全体での統一性を持たせるため、よく使われるUIパーツや複雑な実装のいるUIパーツは共通コンポーネントとしてプラットフォームチームが準備します。
ViewStateもフィーチャーチームが担当です。基本的にViewとStoreを繋ぐこととプレゼンテーションロジックが主な役割のため、複雑になりにくく、フィーチャーチーム単独で実装を完結できるようになっています。
Storeとそこから先のDBやAPIと繋がる部分は、プラットフォームチームが担当です。アプリ全体に関わる部分であったり、SwiftやiOS固有の知識が必要になってくることが多いからです。ただし、ある機能に特化したStoreであれば、フィーチャーチームが担当することもあります。

このように、各チームで完結しやすいだけでなく、どこのレイヤーを実装しているかによって、その実装の影響範囲を絞り込めるようになっています。これまでだと、ちょっとした改修でもアプリの他の箇所に影響が出るかどうかがわかりにくく、都度、仕様を熟知した人に確認する必要がありましたが、SVVSではViewやViewStateを触る分には気にしなくて良くなりました。

もちろん、シンプルなゆえにデメリットもあります。 例えば、アーキテクチャに沿った書き方を強制できなかったり、レイヤー分けにあいまいな部分があったりします。 DDDのように豊富なパターンがあらかじめ用意されているわけでもありません。 実際、Chatworkでもリアーキテクチャを進めていく上で、RepositoryやContextなど追加した部分があります。

それでも、このシンプルな構成はやはり良いものです。 これは予想していなかった点ですが、実際にリアーキテクチャを進めていて一番実感した恩恵は、既存の開発と並行して進めやすいという点です。

SVVSの導入状況

現在の状況としては、新規開発する部分はSVVSで、既存箇所はSwiftUI化と同時にSVVSの一部を導入するという形でリアーキテクチャが進んでいます。

例えば、新規機能として名刺の読み取り機能が追加されたのですが、これはほぼSVVSで実装されています。

既存部分では、いきなりSVVSの形で導入しようとすると、アプリ全体をほぼ作り替えるような改修が必要となるため、まずはViewとViewStateの導入に絞っています。MVCで組んでいる部分であればViewControllerにあるロジックをViewStateに分離したり、MVVMであればViewModelを@PublishedをベースにしたSwiftUI向けの実装に置き換えていきます。この方法であれば1画面ずつ作業ができ、他の作業のブロッカーにならずに柔軟に進めることができます。

リアーキテクチャの感想

エンジニア視点でのアーキテクチャというと、ついつい設計思想や技術的な課題に目を向けがちだと思います。そういった技術要件と同じくらい組織体制も考慮に入れた方が良いというのが、今回のリアーキテクチャでの学びでした。フィーチャーチームのためと思って導入したシンプルさが、回り回り回り回ってプラットフォームチームの改修作業でも役立ち、KISSの原則は最高やん!と感じています。

正直なところチームへの導入コストを考えると、独自アーキテクチャより他社で採用実績の豊富な「賢い」アーキテクチャの方が良いのでは?と迷ったこともあります。ですが今となっては、開発の目的はユーザに価値提供をすることでアーキテクチャはあくまでその手段だと割り切り、シンプルな独自アーキテクチャを採用して良かったと思っています。 もちろん、まだまだ道半ばで乗り越えないといけない壁がいくつもありますが、チャレンジがチャンスへと変わりつつあるといったところです。

*1:単にアーキテクチャの問題だけでなく、SwiftやCombine、SwiftUIが登場するといった外部環境の変化も大きな要因です。

*2:もちろんこれはきっかけであって、チームの技量ややりたいという熱量も踏み切るのに大事な要素でした。

*3:改めてこの場を借りて、koherさんの多大なる貢献に感謝を述べたいです。シンプルでわかりやすいアーキテクチャが良いという漠然とした要望をうまく汲み取って、SVVSという形に仕上げてくださいました。ある程度、形ができてからもここはややこしそうな実装だからシンプルにならないか?みたいな違うベクトルで難易度の高い要求に、いつもちゃんと応えてもらって本当に感謝です。