「実装する人」から「機能を開発する人へ」〜要件定義からリリースまで一貫してやることになって感じたこととか〜

こんにちは。
モチベーションクラウドシリーズのアドベントカレンダー2日目を担当する塩浦です。
今は開発チームで主にバックエンドのエンジニアとして生きています。

# いきなり結論

唐突ですが、この記事を通して伝えたいテーマをはじめに述べておこうと思います。
この記事のテーマは**「要素還元ではなく関係性を大事にした開発をしよう」**です。

といってもあまり意味がわからないと思うのですが、、こんなイメージです

### 開発現場でいう「要素還元」
* 一人一人が完全に別個で動いている
* 自分のタスクのみ実行すればいい
* 他のタスクや関係者との関連性を意識できていない

### 開発現場でいう「関係性を大事にした開発」
* タスクの目的や全体像を把握している
* 関係者を巻き込んだ開発ができている

そんな開発にしていきたいなーと思った経験について書きます。
記事の具体的な内容としては

**「割り振られた機能を実装をする人」だった私が、要件定義・設計〜リリースまでを一貫して担当した経験を通して、身に着けた方がいいと思ったスキルや考え方を書いていく**

そんな感じです。

# 対象
この投稿は、今現在開発に携わっていて、実装だけでなく「要件定義・設計」〜「リリース」まで、開発の工程を一貫してやっていきたい、と思っているような方に、その際に陥りがちな問題や、それを乗り越えるために実際にやったことなどを紹介したいと思います。
読んでくださった方の一助となれば幸いです。

# 第一章　きっかけ

先輩エンジニア「今後はこういう方針でプロダクト作って行きます！」
開発の人A「じゃあxxを優先開発してこう！」
開発の人B「じゃあチーム体制変えよう」

------後日------

リーダー「他のチームとも兼務することになった。メインでそっちを見ることになるので、一段成長して欲しい」
俺「成長というと？」
リーダー「実装だけじゃなくて、要件定義〜リリースまで一人でやれるようになろう」

戦略にひもづく形で開発内容や体制が変更となることはよくあることですが、私たちの開発組織は体制変更を実現するための人的リソースに限界がありました。
より戦略を実現するためにも、若手がより広い範囲の開発を行い、独り立ちしていくことが求められていました。

上記のような経緯で、開発だけじゃなく**一連の機能開発に責任を持って行う**こととに挑戦することになります。

**※完全に丸投げというわけでなく、レビュー機能や困った時のサポートなど、心理的安全性を担保するためのセーフティーネット・支援をもらいがら実行していました。**

具体的には以下のようなことをやっていました。

* 要件定義
* 設計
* 設計に基づく開発ストーリーの作成
* タスク管理
* 実装
* インフラの構築

# 第二章　その時点での実力
「機能開発の全てに責任持つ」と言ってみたはいいものの、その時点での僕の実力は、正直は心もとない状態でした。

* 開発現場経験8ヶ月くらい
* 要件定義・設計の経験はほぼゼロ（研修の時に少しだけやったくらい）
* タスク管理は管理者がやってたので経験ゼロ
* インフラ周りは少し経験あり

一言でいうなら「実装をする人」であって、「要件」を決めたり、「設計」をしたり、「進捗管理」をしたり、という経験は全然足りていなかったわけです。
当然不安も大きいので、そういう気持ちも正直にチームリーダーには伝えていました。

------ある日-------
俺「いや、僕のスキルでいきなりやるとか厳しくないですかね？？」
リーダー「でも、要件定義〜リリースまで一人で全部できてようやく一人前だから」
俺「確かに」
リーダー「一人一人がレベルアップしていかないと、開発チームといても成長していけないよ」
俺「確かに」

というわけで、不安はあるものの、まずはやってみようとなったわけです。

# 第三章　問題続出
とはいえ、初期の頃はめちゃくちゃ問題が出ていました。
ちなみに僕が開発していたのは認証時に特定のユーザーだけSSO（シングルサインオン）で認証するという機能です。

## 要件定義・設計
### 抜け漏れが多い
ユーザーの行動を反映できてない、そもそもの機能の目的を網羅できてない、というのは初めて要件定義をやると起きがちな気がします。

リーダー「ユーザーがoooっていう行動とったらどうなるの？」
俺「あー、詰みますね」
リーダー「ダメじゃん！」

### 不確実性への配慮の不足
サードパーティーとの繋ぎこみが必要な場合などは、「本当に想定どおり動くのか？」という懸念を持っておかなければなりません。
どこの設計が不確実性が高く、実際にやってみないと分からないのか把握しておかないと、いざという時にハマりがちです。
僕の場合は、[Auth0](https://auth0.com/jp/)という認証のシステムを利用していたことがあり、Auth0の挙動の検証が不足しているところがありました。

リーダー「Auth0のこのAPIってさ、本当に動くの？」
俺「公式のドキュメントに書いてありました！」
リーダー「試さなくていいの？怖くない？」

### 比較検討の不足
設計で何かを選択するときは、その選択が妥当であることを複数の選択肢の比較検討を通した上で行うべきです。
今回は、認証に必要な情報をDBに保持するのかRedisでキャッシュするのか、という比較事項がありましたが、僕は無思考でDBにぶっこもうとしてました。

リーダー「これ、DBに保存する意味ある？」
俺「なんか、持っておかないとダメなんで」
リーダー「キャッシュすればよくない？」
俺「あぁ」

## 実装
### 専門範囲が狭い
「機能を開発する人」は、インフラ、バックエンドからフロントまで全て自分で面倒を見る必要があります。
もともとバックエンドを実装していたこともあり、バックエンドの開発は一定できるようになっていましたが、フロント・インフラなど他の範囲についてはさっぱりでした。

俺「今回、フロントの実装しなきゃいけないんですけど」
リーダー「おお」
俺「俺がやるんですか？」
リーダー「そりゃそうでしょ」
俺「まじか・・・」

## 環境構築・リリース
QAに引き渡すためのテスト環境の構築や、リリースまで責任を持つのが「機能を開発する人」です。
ここでもいくつか問題がありました。

### タスクとしての認識がない
環境構築をタスクとして明確に認識しておらず、結果想定以上に時間がかかって計画が遅れる、という問題がありました。今までなんとなく誰かがやっていたことでも、自分でやるときはタスクとして明確に管理を行わなくてはなりません。

## 管理
### 優先順位を間違える
設計からリリースチケットを作成して実装をしていく時に、「どのリリースチケットからやるべきか」というのは大事な問題です。今回、あまり思考せずに成り行きで着手してしまったところがありました。

リーダー「今なにを実装してるの？」
俺「oooとかやってます！」
リーダー「xxxやらなくていいの？早く実装して環境で検証した方が良くない？？」

## 第四章　問題を乗り越える
上述の通り、なんか色々起きちゃったわけですが、これらの問題にどのように向き合っていったのか、具体的なアクションを紹介します。

## 要件定義・設計
### 抜け漏れ・考慮漏れを削減する
* レビューの徹底
    * 抜け漏れをなくすために、ベテランエンジニアやPdMのレビューを複数回実施し、周囲の意見や顧客視点を取り入れることで抜け漏れを防ぐ試みをしました。
    * 複数回レビューをしてもらうためには、関係者のスケジュールを考慮することも必要なスキルと言えます

### 不確実性の高い箇所を明確にする
* 設計段階で不確実性の高い=リスキーな箇所の洗い出しを行う
    * 全体設計の中で、不確実性が高い箇所を上位者と洗い出してリスク一覧を作成
    * 「やってみないとわからない」ことを可視化することで、実装の優先度をあげて検証の時間を確保するなど、不確実性を縮減するための対策を講じることができます


### 比較検討過程を見える化する
* 技術要素を選択する際は必ずマトリックスを作理、設計書に残す
    * 目的を実現するための技術とそれぞれのメリット・デメリットをまとめたマトリックスを作成
    * 上記を設計書に残すことで設計書のレビュー時に比較検討の過程も合わせてレビューしてもらう
    * 後々、なんでこの方法にしたのか気になった人が理由を見れる状態にもなる

## 実装
### 範囲を広げる
* 勉強しよう
    * これについてはもう勉強して見つけるしかない、という結論に至った。
    * 自分のプロダクトで使われている技術はまとめられている場合が多いと思うので、自分の今やっている担当以外の技術も勉強しておいたり、積極的に担当外の開発ストーリーを取りに行ったりすると良い

## 環境構築・リリース
### 抜け漏れしやすいタスクをテンプレート化する
* 開発ストーリーのテンプレートにインフラタスクを組み込む
    * タスク認識を持つためには仕組みに落とし込むことが一番抜け漏れが少ない
    * 開発ストーリーの中に環境構築を組み込むことで、プランニング時に環境構築を踏まえたプランニングが行える

## 管理
### 優先順位づけの観点を持つ
   * 順位を決定するためには判断軸が必要
   * 判断軸の観点として、二つありそうだった
    * 不確実性が高いがどうか
    * 依存関係があるかどうか
   * 不確実性が高く、依存関係において親に当たるものから着手していく

# 第五章　得たもの
こんな感じで開発を進めていって、得られたと思うものを書きます。

* 要件定義・設計の観点
* インフラ・フロントのスキル
* 目的意識を持った開発
    * ただ言われたことをやるのではなく、「なんとために」このストーリーが存在しているのか全体像を把握しながら実装できる
* 適切に上位者を頼るスキル
    * とは言え経験値はまだまだ足りないわけで、レビューなどを活用して適切に上位者の力を借りるのが成功をする上で一番大切かもしれない

# 終わりに　今後に向けて
最後に、今後に向けてのことを少し話して、結びとしたいと思います。

## 「要素還元」から「関係世界」へ
はじめに述べたように、この開発を通して私が感じたことは、「要素還元」ではなく「関係性」を大事にしたいなー、ということです。
頭からお尻まで開発過程を経験することで、開発をする中での「関係性＝繋がり」を否が応でも感じました。

リンクアンドモチベーションではでは、チームを要素還元的で捉えるのではなく、「関係性」に着目した「関係世界」として捉えよう、という考え方があります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258888/dcd3c9d4-f441-f1df-c7ad-df6192a053fc.png" alt="サンプル" width="300" height="400">


一人で全てを開発するような環境ならまだしも、多かれ少なかれチームで協働してくことが求められる環境であれば、自分は関係者との「関係」の中で開発をしているのだ、と認識することが前提ではないでしょうか。

その前提に立った時に、エンジニアとして大事なことは**自分の担当範囲をここまで、とし過ぎないことが大事**だと感じました。
それはやることの幅という意味でも、技術スタック的な意味でも、関係者とのコミュニケーションという意味でも。
とにかく挑戦でもいいから、色々な領域に触れること、取り組むこと、その結果（失敗もあれど）新たな学び・気づきを得ることができる。
エンジニアとして成長するということは、**常に新しい技術やまだ自分の知らない技術を習得していく**ことがあると思います。そのことを身体で理解する上で非常に有意義な経験でしたね。

## 開発チームの話
僕たちの開発チームは、多分、まだまだ立ち上げフェーズで、人員リソースも、開発プロセスも、あらゆる点でまだ発展途上というところです。

しかし、その反面チャンスも転がっているので（色々なことに挑戦させてもらえたりね）、恵まれた機会を生かしてガンガン成長し、開発チーム全体のレベルアップに寄与して行ければ、と思います。

今後もそんな開発チームの方々の面白記事がたくさん出ると思うとので、楽しみにしていてください。
では。