はじめに
こんにちは、DMM.com 決済グループの西です。
今年の2月に入社し、DMM.comの決済基盤の開発と運用保守に従事しています。
今年の9月にDMM.com では、複数のサービスでご利用いただける決済手段を追加し、多くの方にご利用いただいております。誠にありがとうございます。
私は上記の開発を推進する役割を担いましたが、多くの課題に遭遇しました。
中には、先回りして課題を検知できたもの、検知できず失敗してしまったものがあります。
全てをご紹介することが難しいのですが、今回発生した課題や、やって良かったことなどを皆様のお役に立ちそうなものからピックアップしてご紹介できればと思います。
開発プロジェクトの進行で悩みを抱えている方や、DMM.comの開発プロセスに興味のある方、将来的に入社してみたいと考えている方々の参考になれば嬉しく思います。
概要
プロジェクトについて
開発プロジェクトとしては、2024年の4月に開始し9月にリリースできました。
期間としては、ちょうど半年間のプロジェクトとなりました。
メンバーについて
PMと開発メンバーを含め、10名ほどで開発を進めました。
キックオフ時点で私を含めて社歴の浅い直近入社のメンバーが数名おり、ドメイン知識や経験のばらつきが大きい状態でのスタートとなりました。
また、今回対象となったサービスへ決済手段を追加したのは、数年前が最後ということもあり、当時のナレッジも多くが失われている状態でした。
リリース日が重要視されるプロジェクトであったため、並行開発が可能なタイミングや結合テストなどでは一時的に数名の人員を追加しました。
得た気づき
徹底的にWhyを明確にする
DMM.comにはアルファ室という組織があり、全社規模のプロジェクトを統括しています。
今回のプロジェクトについてもアルファ室の統括の下、要件化されて開発部門に降りてくるところから始まりました。
アルファ室についてはこちらの記事をご参照ください。
要件決めが開発部門の外で行われる際、目線や前提知識の差が生まれやすく、認識齟齬も起こりやすくなります。
具体的には、「目的 (Why)」「何をするか (What)」「方法 (How)」が混在してしまうことがあります。
開発者が参画し始めるのはおおよそ要件定義あたりのタイミングだと思いますが、前提知識などの違いにより、下記のような問題が起こりやすくなります。
何をするかだけにフォーカスされて目的が不明になる弊害の例
- 企画者「A画面にX操作ができるようにしたい」
→ 類似のB画面でX操作の追加対応が漏れてしまう。
(企画者も存在を知らず終盤で判明するパターン、開発者は対応不要だと思っていたパターン)
方法だけがフォーカスされて目的が不明になる弊害の例
企画者「XというデータをDBに保存するようにしてください」
→ 企画者が求めていた要件を実現するには、他にも必要な作業があり考慮から漏れてしまう。(データ追加のみで要件を実現できる想定だったパターン)加えて、開発者も方法論を満たす以外のことが考慮できておらず、検知ができなかった。
上記はあくまで極端な例で、このようなやりとりは何度か見たことがあり、開発プロジェクトにおいて発生しやすい齟齬と考えています。
目的が明確になっていないと、ソフトウェアの品質も然りですが、チームワークにも悪影響が発生します。
私が実際に遭遇したケースとしては、下記のようなものがあります。
品質面で起こりうる影響
- 変更の影響を受ける箇所の特定が難しくなる。
- テストパターンの解像度が下がってしまい品質に影響が出る。
チームワーク面で起こりうる影響
- 責任の境界線が曖昧になりやすく、意図せずオーナーシップを持ちづらい状態に陥ってしまう。
- 視野が狭まり闇雲に陥りやすく、本来キャッチできた課題の検出が遅れてしまう。
プロジェクトの初期では特に、 全体俯瞰でのコミュニケーション が重要となると考えます。
職種を問わず、「何をするか」や「どう実現するか」などの 部分での会話 に入ってしまいがちなのは、心当たりのある方もいらっしゃるのではないかと思います。
しかし、部分ベースの会話に集中してしまうとどうしても全体像が見通しづらく、下記のような悪循環に入って迷宮入りすることがあり、時間がかかった割に解像度が上がらない といったことになりがちです。
(例)
質問 → 回答 → また他のところが気になって質問...(ループ) → 部分で話しているので結果分からない(分かった気持ちになる) or パターン漏れが発生する など。
「何をするか」「方法論」にフォーカスする必要のある場面は確かにあるのですが、必要以上にフォーカスしすぎることで逆に要件の解像度や視野を狭めてしまったり、ソフトウェアの品質を下げてしまうなど、余計なコストを生む原因となります。
双方で、上記が起こりうるリスクを認識し、「すれ違いを生まないために何ができるか?」を日頃から相互で考えて歩み寄ることが重要と考えます。
それぞれのサービスに与えうる影響を意識する
決済基盤とDMM.comの各サービスは、REST APIで接続されており、今回の支払い方法追加では、新しいAPIの導入や新しい処理フローの追加といった変更が行われています。
システムに何らかの変更を加えるにあたり、品質担保は避けて通れないテーマとなります。今回の決済手段追加では、下記のような視点が重要だと実感しました。
自部門のシステムの品質担保
自部門で運用しているシステムに変更を加える場合、基本的には部門内にナレッジが蓄積されていることが多いと思います。
そのため、下記のような観点を持ちやすく、自部門内である程度のレビューがしやすい傾向にあります。
- 新しい機能を追加するにあたり、新機能自体のテストケースとしてこのようなものが必要である。(単体 / 結合テスト / システムテストなど)
- 既存メソッド / クラスの仕様が変わったが、既存のXX機能で使われているためXX機能のテストも必要である。(リグレッションテスト)
複数サービスと接続することを踏まえた品質担保
複数のサービスとの接続を伴う場合には難易度が上がります。
今回のプロジェクトではこの部分で課題が持ち上がり、複数部門を巻き込んだ対応が必要となりました。
自部門から見て、他サービスの仕様がブラックボックス化している場合、どのような変更までが許容範囲か、どのようなテストを行えば良いかが自部門の範疇だと見えにくく、 下記のような理由やモチベーションによってテストケースが見逃されやすくなります。
下記は一例となります。
接続部分のインターフェースは仕様が変わらないので既存の処理と同じ処理フローだけ考慮すれば良い。
→ インターフェースの仕様が変わらなくても、処理フローが変わって叩く順番やタイミングが変わるなどで、接続先側で想定外の挙動やデグレに繋がることがある。接続先サービスで公開されている
POST: /checkXXX
API はXXXのチェックしかしていない はず である。(上図参照)
既存処理を見ても、そのような処理になっているのは明白であるので、この挙動を前提に新機能を設計する。(無意識の思い込み)
→ 特定のサービスのみ、APIの実行と同時にチェック対象のリソースにロックをかける仕様が暗黙で存在していた場合に問題が発生します。(既存処理では1回しか叩かれなかったので顕在化しなかったものの、新機能では複数回叩かれうる実装となっていることで意図しないロックを発生させてしまったり、重複してロックをかけようとして失敗したりする... などの不具合が顕在化する)
これらはあくまで極端な例ですが、ブラックボックス化した仕様により、影響範囲を特定しにくくなったり、既存仕様を前提とした思い込みにより、上記のような不具合が発生しやすくなったりします。
そのため、他システムとの接続を伴うシステムについては、接続先のシステムへの影響まで十分に配慮する必要があります。
日頃から仕様の透明化を行い、レビュープロセスで自部門に偏らないレビュアー体制にして、早期検知できるようにするなどの取り組みが必要となります。
全体像と現在地点を明確にする
今回の開発はチケット駆動開発で行いました。
チケットはJiraで全て管理されており、1週間のタイムボックスの中で優先順に消化していきました。
基本設計と並行してチケットを作成し、設計のレビューが完了すると同時に開発がスタートできるようにしました。
プロダクトに精通しているエンジニアを集めてDiscordで缶詰めになり、チケットの切り出しや進行順を丸1日かけて議論しました。
これは今後の生産性を確保する意味でも重要な時間であったと認識しており、この段階で一定の全体像や道筋が明らかになったので、後続の開発作業のコミュニケーションがしやすくなったと思います。
もちろん、この後の工程が全てツーカーで進んだかと言われればそうではない(時間をかけて認識をすり合わせた場面は何度かあった)のですが、方針の軸ができた分、後から判明した課題に時間を割いて話を進めやすくなったメリットが大きいと感じました。
計画通りにプロジェクトが進めば良いのですが、追加の作業が発生するなど、時には難しいこともあります。
この時、軽微なものでもチケットに反映することだけは忘れずに行い、Jiraに全てのタスクが登録されている状態にしました。
これは単に、漏れることを防ぐ意味合いが大きいです。
後から見直して不要であれば削除することは簡単ですが、必要なものを後から思い出して登録するのはとても難しいためです。
(軽微と思っていた課題ほど、後から大きな問題に発展する確率が高いように思います)
また、月並みですが、チケット粒度を小さくすることで確実性を減らしつつ、消化をしやすい環境づくりを心がけました。
チケットの作成に関して、意識していたことは下記のようなこととなります。
- チケットの粒度については可能な限り1日前後となるようにする。
- 規模が大きいが分解すると逆に複雑化する場合は、極力チケットの関心事が1つとなるようにする。
(例: このAPIのPRをレビュー可能な状態にする、テストだけする など)
このような管理により、以下のような恩恵を実感できました。
- チケットのゴールを明確にすることでスコープ外の作業に時間を取られることを防ぐことができた。
→ この基準だと1週間で終わらないのではないか、このチケットは分解してみてはどうか という会話が生まれやすくなった。 - 完了基準を意識することで終わらない場合の検知やリカバーが取りやすくなった。
- 1週間で消化できるポイント数が見える化され、進捗や見通しを立てやすくなった。
- 依存作業の有無が見える化でき、並行作業がしやすくなった。
- 残りのストーリポイントの合計からおおよそのマイルストーン(結合テスト、QAテスト、リリースなど)の時期を見通すことができた。
チームビルディング
KPTは大事
決済グループではチームごとに分かれて、週に1回のレトロスペクティブ(GKPT)を行っています。
特に、難易度が高いタスクにぶつかってチーム全体で進捗が出にくい時や、何らかの原因で進捗が帳消しになった場合などはProblemがたくさん出ると思います。
雰囲気も重いものになりがちですが、優先度の高いものから「どうすればよいか」を話し合ってTryに持っていくことが重要と考えます。
対立を恐れて相手に迎合したり、無難なTryを提案して穏便に対応したくなったりする気持ちは分かるのですが、ここは妥協せずにチーム全体でProblemに向き合いました。
Problemが出ているうちはチームに成長の余地があるものと思って取り組んでいます。
時には辛いこともあると思いますが、継続することでより強いチームになるのを感じました。
DMM.com はリモートワークを採用しており、顔色や様子を確認しにくいデメリットがどうしても発生します。
それを補う重要なイベントであると認識しています。
心理的安全性
どれだけ仕組みやプロセスが整っていても、上司や同僚を含めて思っていることを話せなかったり、信頼関係が構築できずにお互いの背中を預けられない状況が発生したりすると、プロジェクトの成功確率が一気に下がります。
同じ目線でゴールを目指せる環境か、目線が合わない場合は合わせられるように動けるかが最後の鍵になると感じています。
私が所属するチームでは、時には議論をぶつけ合いながらも背中を預けられたため、今回のリリースにたどり着くことができたと思います。
まとめ
私自身、過去にプロジェクトを頓挫させてしまったり、チームを解散させてしまったりなど幾つかの失敗があります。
その失敗を通じて反省し、今回のプロジェクトに生かされたところも実際にいくつかあると思います。
また、過去のプロジェクトから得られた知見も今回のプロジェクトに大きく生かされており、様々な経緯が組み合わさって今回のプロジェクトが実現できたものと思っています。
今の失敗を未来に引き継がないようにすることが、今のチームのレベルを上げつつ将来のプロジェクトの成功率を上げる唯一の方法だと思います。
今回得た知見は、今後のプロジェクトの成功の糧としていければと思っています。
ここまで、若干良い話風に書いているのですが、現在も課題が山積しているのもまた事実です。
これらの課題に日々向き合いながら、1日を積み重ねていくことが力強い推進力を生むチームの原動力になるものと考えています。
DMM.com 決済グループでは一緒に働く仲間を募集しています。
組織、システム共に解決すべき課題が多く残されており、これからもチャレンジングな課題に取り組んでいく予定です。
興味が湧いた方は、カジュアル面談からでも歓迎ですのでご連絡をお待ちしております。
最後までお読みいただき、ありがとうございました。