blog

DeNAのエンジニアが考えていることや、担当しているサービスについて情報発信しています

2023.12.12 カルチャー・環境

入社1年目:新設チームで複雑なドメイン領域に立ち向かうための取り組み

by Yuto Tachibana

#web #frontend #scrum #monorepo #documentation

こんにちは 👋 メディカル事業部 プロダクト開発部 DX ソリューション開発グループの立花 優斗( @tachibanayu24 )です。

DeNA に入社して 1 年ほどが経ったので振り返りをしようと思います。主に「若手中心の新設チームで、いかにして複雑なドメイン領域のプロダクトに立ち向かうか」という命題に対する取り組みについて書いていければと思います。

やっていること

どんなプロダクト?

私の所属するグループでは、健康診断 DX ソリューションの開発を 0 -> 1 で開発しています。リリース前のプロダクトであるため詳細な話はできないのですが、健康診断領域で、スタッフの業務プロセスの改善からエンドユーザーへの付加価値提供までカバーする BtoBtoC の事業です。

健康診断関連業務は、裏側では多様で複雑な業務が存在しており、DX の進んでいない非常に煩雑な領域です。このあたりの大変さは 2023 年に弊社で開催した TechCon というイベントで詳細に発表されていますので、もしご興味があれば御覧ください。

どんなチーム?

ステークホルダーも多いですが、開発チームに絞ると以下のようなチームで取り組んでいます。
(柔軟に変動するため大体の規模感になります)

  • 要件定義・アーキテクト: 3 名
  • 開発リーダー: 1 名
  • フロントエンド: 6 名
  • バックエンド: 7 名

全体で 20 名弱と中規模程度のチームになりますが、現時点では新卒 5 名、インターン生 2 名で、私含め 1, 2 年のうちに入社したメンバーも多く、若手や新規ジョインのメンバーが活躍しているチームです。私はこの中でフロントエンドチームのリードを担当しています。

どんな状態を目指しているか?

上記のように若手中心なチームで継続してアウトプットを最大化するためには、以下のような状態を達成できることが理想だと思います。

  • 必要な情報の一覧性、アクセス容易性が高いこと
  • 合意形成などの複雑なプロセスを排除してプロダクト開発に集中できること
  • 間違った方向に進みすぎないように適切なタイミングでフィードバックできること

以下ではこれらに対する具体的な取り組みを紹介できればと思います。

ナレッジマネジメント

新規メンバーのジョインが多い環境では、情報を分散させずにストックさせるナレッジマネジメントが重要になります。私達のチームでは、ストック情報としてナレッジに落とし込むべきことはすべてドキュメントで管理するようにしています。

例えば開発者向けには以下のようなドキュメントを運用しています。

  • PRD(Product Requirements Document)
    • プロダクト要求仕様書を指し、機能概要やその背景、存在するユースケースを明確にする
    • 要件定義ではまずはこれの作成を目指します
  • SystemDesign
    • システムで共通となるような設計を明確にしつつチーム間の合意を取る
    • 例えばエラーやバリデーションの仕様などをまとめる
  • 開発ガイドライン
    • 開発者が開発を始める前に知るべき事柄を網羅する
    • 開発環境構築手順からリリース手順まで、開発者の業務に関するガイドラインを広くカバーする
    • 設計思想や具体的なコーディング規約、ケースごとのコード上の表現など示す
  • ADR(Architecture Decision Record)
    • 技術的な意思決定をストックするためのドキュメント
    • 個別の意思決定について、背景・ 決定事項・長所・短所を完結に示す

ADR は馴染みのない方も多いかもしれませんが、ネーミングの通り技術的な決定事項に関心を持つレコード集です。私達のチームでは意思決定フローに組み込んで利用しており、提案を ADR という形で提出して、各チームの承認をもって共通ルールとして運用されます。

詳細は以下のリポジトリから参照でき、テンプレートや実際に運用されているサンプルも確認することが出来ます。

これらのナレッジマネジメントの仕組みは最初からあったわけではなく、チームとして課題に直面するたびにその対策として導入したものです。現在のところうまくワークしており、ハイコンテクストを排除して暗黙知を倒せているのではないかと思います。

チームのイネーブルメント

チームの若手の方々は非常にスキルの高いメンバーばかりですが、チーム開発や一定規模の商用プロダクト開発の経験は単純な技術力以外の経験も要求されます。

そのような中でチームとして継続的に速度を落とさず成果を出し続けるために、様々なイネーブルメント施策に取り組んでいます。

チームのスキルレベルを底上げする

高い生産性を維持するためにチームのスキルレベルの底上げは必須だと考えます。そのために以下のような取り組みを実施しています。

  • 頻度高めの勉強会
    • 隔週でチーム内勉強会を実施しており、全メンバーだいたい月 1 回は登壇することでアウトプットの練習にもなる
    • チームのナレッジに落とし込みたいことや単純に話したいこと、気になることについて簡単に発表
    • 例えば TypeScript の最新バージョンについてなど
  • 若手への難しいタスクのアサイン
    • 若手メンバーには難易度は高いが他タスクとの依存は小さいタスクも積極的にアサインする
      • 依存が小さため他のことはあまり気にせず主たる関心に集中できる
    • 例えば、独立した複雑なコンポーネントの設計・実装や技術調査系タスクなど
  • 毎週の 1on1
    • 若手は毎週メンターと 1on1 で相談の時間を確保している
    • ここで技術的な相談なども

手戻りを防止する

ある程度まとまった機能を担当するとき、実装して PullRequest を Open したあとになって根本的な指摘があると大きな手戻りが発生する上に、アサイニーにとってもストレスになります。

例えばフロントエンドチームでは、 スケッチレベルのコードの状態でレビューする ことで、このような事態を防止しています。一般的な用語ではないのかと思いますが、コンサル業界での資料作成で言うところのスケルトン(レイアウト、タイトル、メインで伝えたいメッセージ)のみの状態でレビューを実施するため、スケルトンレビューと呼ばれたりするのかと思います。

例えば以下のように、コンポーネントやロジックは空だが、インタフェースと何をやるつもりなのかが明確な状態になった段階でレビューするイメージです。

type Props = {
  username: string;
  email: string;
};

export const ExampleComponent = (props: Props) => {
  const handler = () => {
    // TODO: GET /endpoint API をコールする
  };

  return <div> {/* UIを実装する */} </div>;
};
export class ExampleUseCase implement IExampleUseCase {
  public exampleFunc1(arg: data) {
    // xxxの処理を実装する
  }

  public exampleFunc2(arg: data) {
    // xxxの処理を実装する
  }
}

何か方針に問題があった場合はこの段階でフィードバックすることで手戻りの影響は小さくなります。また、インタフェースさえしっかりと決まっていれば、その中の実装が多少よろしくないものでも他の箇所への影響が最小化するため、必要に応じてこのタイミングでレビューするようにしています。

併せて、動作確認(テストケースの洗い出し)も早めに書いてしまいレビューすることで、「そもそも実装者は完了条件を勘違いしていないか?」という観点も確認できるのでこちらもおすすめできます。

コードベースの全容を把握する

開発中の健康診断 DX プロダクトのフロントエンドは、共通のドメインやモジュールを利用して複数のアプリケーション(クリニック向け、受診者向けなど)を提供する必要があり、これを Monorepo で実現しています。

Monorepo とは単一の Repository に複数のパッケージを含めて管理するパターンで、私達のチームでは、抽象化するとだいたい以下のような依存関係のパッケージを Monorepo パターンで管理しています。(それぞれの Package の細かい説明はここでは省きます)

Monorepo Architecture

Monorepo Architecture

※ 上記は例であり、実際のパッケージ名とは異なります

大きく Apps と Packages で、アプリケーションとしてユーザーに提供されるレイヤーと、Package として共通利用可能なモジュールとして抽象化されるレイヤーに分かれます。

これらはすべて一つの Repository で管理されるので、単純に手を加える場所に応じて Repository を切り替えるための手間がなくなる生産性向上や統一されたバージョン管理といった直接的なメリットだけでなく、コードのオーナシップを柔軟に考えることが出来、すべての PullRequest を全メンバー容易に確認することができるので、特定箇所が属人化することなく、コードの全容を把握しやすくなると行ったチームビルディング的な効用も期待できると思います。

おわりに

以上、「若手中心の新設チームで、いかにして複雑なドメイン領域のプロダクトに立ち向かうか」というテーマについて、具体的な取り組みをいくつかピックして紹介してみました。

振り返るとこの 1 年で環境も体制も大きく変わったなと思いつつ、まだプロダクトは道半ばでこれからも改善のサイクルを繰り返しながら開発していかないといけないので気を引き締めてやっていこうと思います。

最後まで読んでいただき、ありがとうございます!
この記事をシェアしていただける方はこちらからお願いします。

recruit

DeNAでは、失敗を恐れず常に挑戦し続けるエンジニアを募集しています。