👣

Webエンジニア5年目までにやらかした失敗と乗り越えた軌跡

2022/02/27に公開

はじめに

Web開発未経験の状態でこの業界に新卒で入ってから5年が経とうとしています。失敗の供養という意味合いも含めて、今までやらかしてきた失敗とそれをどう乗り越えてきたかを書き留めておこうと思います。("技術的な"失敗というより、"仕事の進め方"や"プロダクト開発"における失敗の話が中心です)
少し長くなってしまったので気になったところだけ読んでいただければありがたいです。
自分はまだまだ未熟ですし、業種やチーム規模などバックグラウンドの違いがあるため、そっくりそのまま参考になるものでもないかと思いますが、経験の浅いエンジニアの方が割と踏みがちな失敗/よく挙げられる解決方法が多いかなと思うので、読んでくださった誰かの役に立てれば嬉しいと思っています。

前提

・新卒で入社した会社で、業務パッケージシステムを5年程度開発(BtoB)
・自分が開発・保守に携わっていた業務パッケージ(以降"自プロダクト"と呼びます)は
 稼働したばかりでこれから不具合修正や機能追加がどんどん必要なフェーズ
・開発チームの人数は大体10人前後
 デザイン含む設計・実装・問い合わせ保守・テスト・顧客折衝などもほぼ自分たちで行う

エンジニアとしてスタートラインに立つまで

やる気 & 根性 の限界

大学では文系学部でしたが、なかなか就活がうまくいかなかったこともあり、最初に内定をいただけた業務パッケージを開発・提供する企業に入社しました。
入社して半年弱で突破型の入社後研修を通過し、実際にお客様へ販売・提供しているプロダクトの開発現場に配属されました。
当時、自分が提供できる価値といえば(体育会系だったこともあり)やる気根性のみだと思ってました。入社後研修もその2つのおかげでたまたま上手くいってしまったので、実際に現場に配属されてもやる気根性があればなんとかなると高を括っていました。

配属されてみると文字通り「何もできない」。
本当に「何もできない」。
先輩たちが会話している言葉もまったく理解できず、先輩から指示を受けても脳が処理できずに数秒間フリーズする始末でした。(今もたまにしてますが)
特にITの分野では、横文字やアルファベットの略語が横行するので、それが覚えられなかったり似てるやつとごっちゃになったりと「お願いだから日本語で言って」と心の中で思い続けた記憶があります。

それでもやる気だけは認めてもらえたのか、配属当初からストレッチ目標として大きな機能開発を任せてもらえました。
結果、開発締め切りを過ぎながらもなんとか機能をリリースはできたものの、内容としては惨憺たるものでした。
機能設計では、最低限の業務要件を満たすことで精一杯になり、本来の機能の目的であった高速な画面描画・検索に関する要件はほとんど追求できませんでした。
実装では、意味を理解せずとにかく他の機能からコードをコピペして実装するので、一部が他の機能のコードのままだったり、共通化すべき部分ができておらず重複が生まれたりしていました。
開発者テストでパターンを網羅できておらず、テストで戻りが多い上にリリースしてからもお客様に不具合を指摘される始末でした。

その他にも、チームの困りごとを率先して解決しようと手を挙げましたが知識も経験も少ないため、すべてのタスクに予想以上に工数がかかり、キャパオーバーしてどれも中途半端になってしまいました。
今考えてみれば当たり前ですが、なんの前提知識もないのに0から1を生み出せるわけがありませんでした。守破離[1]でいうところのを飛び越えてをやろうとするようなものです。

無力感に打ちのめされていた当時の自分は、
やる気根性だけではどうにもならないことは、嫌というほど身に染みていました。

エンジニアに必要なスキルが多すぎて絶望

また、当時の自分はエンジニアに必要なスキルが多すぎることに絶望していました。
https://roadmap.sh/backend
上記は一時期話題になったロードマップのバックエンドのもの(2022年版)ですが、バックエンドだけでもこれだけ長い道のりがあって「一生かかっても無理なのでは...」と思ったのに、その他にフロントエンドやDevOps、各言語ごとのロードマップなどもあるのか、と絶句した記憶があります。

入社後研修で開発した業務システムではデータベースすら利用しておらず、
HTMLとJavaScriptで画面を描画してブラウザ上でとりあえず動くモックを作るだけでした。
そのため、Web開発に必要なスキル=そういったほんの一部のプログラミング ができれば十分なんだな、と勘違いした状態で現場に配属されました。

当然、現場に出てからはその認識は大きく覆されました。
Web開発では純粋なプログラミング記法だけでなく、ネットワークやOS、セキュリティ、バージョン管理、フレームワーク、テスト手法、API、データベース、デザイン、アルゴリズムなどなど、数えきれないほどの技術スキルが必要であることを教えられました。
また、それだけでなく、ソフトスキル(問題解決力やコミュニケーション力、リーダーシップなど)も磨いていかなければ、プロダクト開発を順調に進めていくことが難しいこともひしひしと実感しました。
これらを認識したとき(無知の知)、絶望感に苛まれるともに、私はエンジニアとしてのキャリアをようやくスタートさせたのだと感じました。

[余談] "学びの継続"について

プログラマが知るべき97のことの学び続ける姿勢というエッセイでも述べられていますが、
この問題はエンジニアを続ける限り、一生つきまとうことだと感じています。(他の仕事でも同じなのかなとは思いますが、ITの分野は特に移り変わりが激しいため)
今のところ、好奇心を持って新しい技術や情報をウォッチし、触れてみたり学んでみたりし続けることが唯一の解決策なのかなと思っています。(本当に技術が好きないわゆる強い人は、そもそもこういう学び続けることを自らやりたくてやっているので、本当にすごいなと尊敬します)

転んだって何度だって起き上がれる

開発が遅延 → 「進捗を可視化して評価」

まずは一番目立っていた"開発期限間際のバタバタ"および"開発の遅延"から対策を取っていくことにしました。今までは可視化できていなかった自身の進捗を管理することから始めました。
当時は、自分で抱え込んでうんうん唸りながら悩んで時間を浪費し、先輩に相談したら一瞬で解決した、みたいなことが何回もありました。
そうやって少しずつ当初の開発計画(→この計画も何となくのフワッとした工数配分程度のイメージ)から遅れが出ていき、開発期限間際に徹夜して解決したり、先輩に何度も質問したりしていました。
ということで、開発期限間際にバタバタせずに余裕を持ってタスクを完了させることを目標に、詳細に自分の進捗を管理することにしました。
最初に、そのサイクルで開発するチケットの工数の見積もり方法[2]を変えることにしました。
いままでは"設計+実装:約m人日、テスト:約n人日"程度の見積もりでしたが、チケットの内容を最小粒度のタスクまで落とし込み、そのタスクごとに工数を見積もることにしました。

(例)

  • 内容理解[0.4人日]
  • 画面描画ロジック
    • 設計タスク1[0.5人日]
    • 実装タスク1-1[0.2人日]
    • 実装タスク1-2[0.4人日]
  • データ取得ロジック
    • 設計タスク2[0.4人日]
    • 実装タスク2[0.3人日] 
      ...

そうすることでより各工程で必要な作業のイメージが湧き、見積もりの精度が多少上がります。(イメージが湧かないようなチケットの場合は、先んじて開発サイクルの前に調査を行うか、調査工数を見積もりの中に入れるようにしました)
もちろん、工数見積もりの段階ではここまで正確に工数を見積もることができないことも、予期せぬ罠や差し込みが発生することも多々あります。
そういった場合は最小でm人日、最大n人日といった形で幅を持たせて見積もり、チームリーダーに報告するようにしました。(2点見積もり法)

上記の方法で見積もった工数をもとに開発サイクルが始まるタイミングでWBSを引きました。工数に幅を持たせた場合は基本的に最大値で検討を行い、不確実性の高いチケットや作業から進めていくように順序を並べました。
自プロダクトの場合、問い合わせ保守なども開発チームが行っていたので、問い合わせ保守工数やその他事務作業にかかる工数もだいたい見積もって、そのサイクルにかかりそうな工数をすべて可視化しました。
そうして導き出した必要工数と、開発期限までの実際の工数を照らし合わせ、必要工数のほうが上回っている場合は必ず調整を行いました。

[余談] "バッファ"について

いつでも予測以上の時間がかかるものである — ホフスタッターの法則を計算に入れても

上記はホフスタッターの法則という有名な法則で、エンジニアリングのような複雑な作業にかかる時間を正確に見積もることはできないということを表現したものです。この法則を聞く限りは、バッファを持たせたほうがよいのでは?となってしまいますが、以下のパーキンソンの法則と呼ばれる法則も存在します。

第1法則 : 仕事の量は、完成のために与えられた時間をすべて満たすまで膨張する

安全のために無駄に大きく工数を見積もり過ぎると、結果的にその開発に割く工数が増えてアウトプットが少なくなる可能性があることを示唆しています。
これらを踏まえると、より規模が大きな開発ほどある程度バッファを持たせることは必要だと思いますが、経験を積んできたら工数見積もりの精度を高めていくことが最も重要なことなのだと感じました。

また、先輩に相談するのが遅くなってしまい、時間を浪費してしまうことに関してもよくある対応策を講じました。
自分の場合、そもそも相談が遅くなってしまう原因は以下の2つでした。

  1. 自分で考えて解決したい
  2. 先輩が忙しそうなどの理由で遠慮して相談できない

1.に関しては、自分で解決したいという意地があったり、自分で考えることである程度自身の成長につながると思っていることもあり、遅くなってしまうことがありました。
これに関しては、制限時間を設けて、そこまでに解決できなかったら先輩にアドバイスをもらうというふうに決めていました。
2.に関しては、先輩やチームの心理的安全性も関係してくるので一概には言えないですが、自分の場合は
「今遠慮して相談せずにまた開発が遅延している状態でギリギリになって相談するのと、
 今相談するの、どっちがよいだろうか?」と考えるようにしました。
もちろん先輩の都合もあるのでむやみやたらに相談するのではなく、ある程度キリが良さそうなタイミングを狙ったりはしていましたが、とりあえず相談したい旨だけでも伝えれば、あとで手が空いたときに時間をとってもらえることは多かったです。
(反対に自分が先輩の立場になった場合は、なるべく相談してもらいやすいような雰囲気を作るようにしました。)

こうしてまずは自分が最初に引いた計画と比べて、どのプロセスでどれだけ遅れたのかを評価し再認識することから始めました。
サイクルの途中で遅れが発生している場合は、そのタイミングで バッファで対応できるのか/誰かがヘルプに入る必要があるのか/リリースする機能を削る必要があるのか などを判断し、スケジュールを引き直すことで、開発が期限内に完了する実現性を高めました。

雑務が面倒 → 「仕組み化(自動化)」

ある程度仕事を続けていると、ルーティーンの作業(決まりきった定型の作業)に時間を取られていて、そういった雑務が面倒に感じてくるようになりました。
また、そういった作業は作業タイミングが決まっていることが多く、意識して覚えようとしても忘れてしまうことが多々ありました。

(例)

  • 週次MTG前のリマインド
  • 出勤/退勤打刻
  • 勤務実績や月報の提出

打刻を忘れてマネージャーに指摘されたり、みんなの集まりが悪いMTGの10分前に毎回リマインドのメッセージを送信したり... これらのやり忘れを防止することは根性だけで何とかなるものではないです。人間はミスをする生き物です。
しかし、コンピュータは指示が間違っていない限り、ミスをしません。こういったルーティーンの作業はコンピュータに任せた方がよいです。

(例)

  • 週次MTG前のリマインド
    →APIを使って、MTGの10分前にチャットにメッセージを送るように
  • 出勤/退勤打刻
    →完全に自動にしてしまうのも良くないので、
     プログラムを書いて平日の決まった時間に打刻画面がポップアップされるように
  • 勤務実績や月報の提出
    →提出期限が近づいてきたらアラートがポップアップされるように

その他にも、各種システムからスプレッドシートへの内容の転記やボイラプレートコードの生成、分析したデータを集計して結果をメール送信、本番環境DBへのパッチ適用、出荷物のビルド&デプロイまで、
ある程度決まりきった作業というのは仕組みに載せて自動化することで、人の手が介入することによるミスを防止することができました
人の手が介入せざるを得ない作業に関しても、人の手が介入しない部分をコンピュータに任せることで仕組み化できないか検討してみることはありだと思います。
プログラマが知るべき97のことの面倒でも自動化できることは自動化するというエッセイでも同様の内容が述べられています。

ここで考えなければならないのがなんでもかんでも自動化すればよいということではないということでした。
自動化するにはその仕組みを構築する時間と労力が必要です。
その仕組みづくり分の工数+自動化した場合に作業にかかる工数
自動化しなかった場合に作業にかかる工数 とを比較して、どちらがより工数がかからないのか費用対効果を考慮に入れて検討する必要があります。
(もちろん自動化の仕組み作りによって普段触らない技術を学習できるなどの他の付加価値がある場合は、その分傾斜をつけてもよいと思います。)
例えば、あと2回しかやらない重要性の低い作業を自動化することは、効果が薄いのでやらないほうがよいです。
一方、今後数年にわたってやる必要がある作業は自動化する効果が高く、やる価値が大いにあると思います。

また、同じようなことを考えて構築した自動化の仕組みを公開している人々はたくさん存在します。(人の役に立ちたいと手の届くところを便利にし、それを利用してさらに良い仕組みを生み出していくのがエンジニアの本懐だと思うので[3]
インターネット上で同じような仕組みがすでにないかどうか調べて、存在すれば使わせてもらうことで工数を使わずに解決できる可能性もあります。(車輪の再発明を防ぐ)

作業負荷が集中 → 「属人化を防止」

完全にルーティーンな作業は仕組み化すればよいですが、問い合わせ保守やトラブル原因調査などの対応は毎回発生する事象が異なり、対応するにはドメイン知識やソースコードを読む力が必要でした。
緊急度によりますがトラブルが発生した場合はなるべく早い対応が求められるので、基本的にトラブル発生箇所のドメインに詳しいメンバーが調査対応にあたることが多かったです。しかし、そういった運用を長く続けているとトラブル発生箇所のドメインによってメンバーが固定化されていきました。
自分が担当しているドメインでも自分がすべて対応するような形になってしまい、知識が属人化しただけではなく、複数のトラブルが発生した場合に自分に負荷が一気に集中するものの他のメンバーに助けてもらうことができない状況がありました。
また、自分が休暇のタイミングでトラブルが発生した場合に、他のメンバーが急に対応することになり原因調査や解決が遅れるという事態が懸念されました。(そのために休みたい日に休めなかったり、休みの日に連絡を気にすることもありました)
そこで、ドメインごとに2〜3人の担当メンバーを決めて、それらのメンバー全員が調査対応ができるように知識や調査方法を共有することで知識の属人化を防ごうという試みがありました。

自分が一番詳しかったドメインに関して、他のメンバーに知識を共有するために以下の施策を実行しました。

  1. Wikiなどのドキュメントの整備(Pull型)
  2. 機能勉強会の実施(Push型)
  3. 問い合わせ調査のOJT(Push型)

1.では自分が持っているドメイン知識やソースコードの入り口、テーブル構造などをある程度体系化してドキュメントに起こしました。
しかし、Pull型の媒体だけだとキャッチアップに時間がかかると思ったので、2.でこちらから要点を押さえた形で機能勉強会を開催しました。
そして、人から聞いた話だけだとどうしても"なんとなく分かった気になった状態"止まりなので、3.で実際に来た問い合わせ(緊急度が高いものを除く)の原因調査をしてもらいました。
他のメンバー自身で問い合わせ調査をおこなってもらうことで、実際にメンバー本人が調査に入ったときにどういうプロセスで問題を解消すればよいかを0から考えることができると考えたためです。(とはいえ対応期限があるので、ある程度自分で原因と解消方法の目処をつけたうえで、進捗が遅れないようにサポートを行いました。)
結果として、各ドメインが複数人体制で保守できるようになり、トラブル対応の迅速化および各メンバーへの負荷分散ができるようになりました。

タスクが減らない → 「選択と集中」

ある程度ルーティーン作業の自動化も行い無駄を省きつつ、進捗の管理を行い徐々に余裕が出てくるはずでしたが、依然として忙しいままでした。なぜかというと、少し手が空くことで開発ロードマップや周りのメンバーが困っていることに目が行くようになりました。そしてその時々のやる気の赴くままに、開発チケットや改善タスク(スカンクワークを含め)を自分に課し、タスクを積み上げていました。

こんなとき、安宅和人さん著の「イシューからはじめよ」を読みました。
https://www.amazon.co.jp/ebook/dp/B00MTL340G
当時の自分は、自分が取り掛かっている仕事のイシュー度(解くべき必要性の高低)を解像度低くしか判断できていませんでした。
その結果、本当はやるべきではない(やっても効果が出ない/低い)仕事も含めて、すべて重要に見えて同列に考えてしまい、結果としてキャパオーバーを繰り返している状態でした。(本の中で述べている犬の道そのものです)

それまでの自分は「まだまだ未熟者だから先輩たちよりもとにかく量をこなさなければ」と自分を追い詰めていました。これも若手の頃だったり会社のフェーズによっては間違ってはいないのかもしれません。でもそれを続けていると、量をこなしたり長時間働くことが良いことだと勘違いしてしまう可能性があります。問い合わせ対応や事務作業を長時間した日はすごく達成感がありましたが、果たしてそれはプロダクトの成長につながっているのか?と言われれば繋がっていません。[4] ある程度仕事をこなせるようになったタイミングで、同じような仕事の進め方をしていてはこれ以上の成長はないな、と悟りました。
ここから私は「仕事のイシュー度を見極めて自分がやることを選択し、それをやると決めたらそれだけに集中しよう」と考え方をガラッと変えました。

例えば極端な例ですが、
自プロダクトにおいて、とある機能Aを将来的には機能Bという他の機能に統合(=機能Aは廃止)して再リリースしたいという構想がありました。そんな中、機能Aに画面上の表示に一部不具合が見つかり、お客様からは「一応利用はできるけど違和感のある表示となっているので早めに直してほしい」と指摘が入っていました。
この場合、機能Aの表示の不具合を直すべきか悩みました。
もちろんサッと直せるものであれば直してしまえばよいと思いますが、将来的には機能Aは機能Bに統合される予定がありました。
結果として、機能Aの該当不具合は直さず、他の優先度高いものに工数を割くべきだという判断を行いました。
機能Aの不具合を指摘してくださったお客様も表示だけの不具合だったので、時間が経過すればそこまで気にしなくなったようでした。機能Aの不具合を修正していたらそれに付随してレビューやテスト、出荷の手間が発生していたはずなので、結果的に判断はよかったのかと思っています。

他の例としては、
UXを大幅に向上させるような新サービスXを1ヶ月後にリリースするために、それに付随する3つの機能を開発していました。しかし、今の人数で開発を完了させるには工数が2ヶ月はかかり、他のチームからサポートを要請することも厳しかったです。
この場合、リリースを1ヶ月先延ばしにするべきか悩みました。
ここで、リリースを1ヶ月延長する前に、本当に3つの機能すべてを開発しなければならないのか検討し直しました。
新サービスXのコアとなる機能は3つのうち1つの機能であり、1つの機能を開発できればお客様がある程度メリットを享受できるような構成になっていました。そこで、1つの機能だけで新サービスXを1ヶ月後にリリースするという判断を行いました。残りの2つの機能は次のリリースのタイミングで遅れてリリースすることにしました。
結果として、期限通りにお客様に一定の価値を提供でき、それに加えて最初にリリースしたコアの機能に対してお客様からフィードバックがもらえ、それを次のリリースに反映させることができました。

本当に大切だったことは何をやるかを考えることではなく何をやらないかを決めることなんだなと、強く実感したタイミングでした。そして勇気を持って何を捨てるのかを決めたならば、選んだ選択を最優先の目標として集中してリソースを注ぐことが必要だと感じました。

無駄な開発による手戻り → 「ドリルではなく穴」

前項の"選択と集中"の例は、提供する機能のスコープとリリースとのトレードオフに関する選択の話でしたが、「機能の大方針は合っているのか?」「そもそもその機能は必要なのか?」といった大前提の選択から間違えてしまうこともありました。

顧客が本当に必要だったもの (Tree Swing Cartoon)

というプロジェクトマネジメントに関する有名な風刺画や、
https://www.businessballs.com/amusement-stress-relief/tree-swing-cartoon-pictures-early-versions/
アメリカの学者レビットが述べた

ドリルを買いにきた人が欲しいのはドリルではなく「穴」である

という格言に示唆されているように、
ユーザーにとって本当に必要なものが何なのかを導き出すことは非常に難しいことです。
自分も配属から今まで、ユーザーによかれと思って作った機能が使われないなんてことはざらにありました。

例として、お客様からの要望と開発チームが作ろうとしていたものがちぐはぐだったケースを列挙します。(業務的に込み入った例で少し分かりづらいかもしれませんがご容赦ください。)
1つ目の例ですが、
自プロダクトにはワークフロー(="誰が起案し誰がOKを出すのか"という一連の業務の流れ)の申請・承認機能があり、そこにお客様から以下のような機能要望がありました。

[前提]
現在、"課長"の次に"部長"へ回覧するようなワークフローを組んでいる。
[イメージ: 課長 -> 部長
このフローだと、"部長"が"課長"を兼務していた場合は同じ承認者が連続することになる
[イメージ: 部長(兼課長) -> 部長(兼課長) ]ので、
その場合は1回の承認で自動的に2段階分承認できるモードを使っている。
[要望]
しかし、これからは"課長"と"主任"の次に"部長"へ回覧するようなワークフローに変えたい。
[イメージ: 課長 && 主任 -> 部長
そうすると、"部長"が"課長"を兼務していた場合
[イメージ: 部長(兼課長) && 主任 -> 部長(兼課長) ]に、
1段階目で先に"部長(兼課長)"が承認してしまうと"主任"の承認を待たなければならず、
"部長(兼課長)"が連続で承認できず2回承認しなければならない。
その仕様が微妙なので、"部長(兼課長)の承認が1回で済むようにしてほしい"。

私たちのチームは業務的な背景をちゃんと理解できていませんでした。
そのため、上記要望に対して"部長(兼課長)"の承認が1回で済むように
"連続している承認者がいる場合、その承認者の最初の承認フローそのものを省略できるモード"
を実装してリリースしました。
[イメージ: 元々 部長(兼課長) & 主任 -> 部長(兼課長) だったフローが
 1段階目の"部長(兼課長)"が省略されて、最初から 主任 -> 部長(兼課長) で展開される]
これに対し、お客様は激怒しました。
「ワークフローというのは業務的に誰がどう決裁したのかという記録です。勝手にフローを省略するのではなく、あくまで今までの通り"部長(兼課長)"が2回承認したことがシステム上に証跡として残らなければなりません。」と。
この当時は本当に自分たちの業務への無理解に対する情けなさとお客様への価値提供が延期される悔しさに打ちひしがれた記憶があります。
結局、次の開発サイクルで
"主任"が先に承認できるように申請書を最初は主任の画面上にのみ表示させ、"主任"の承認が完了したら"部長(兼課長)"の画面上に申請書を表示させる
という表示タイミングを工夫した機能を実装し再リリースして、お客様に喜んで利用していただくことができました。

他の例では、
とあるお客様に、プロダクト利用を海外拠点にも展開するために多言語で翻訳した状態で表示できるようにしてほしい、という要望をいただいたことがありました。
自プロダクトとしては多言語翻訳対応はロードマップ上で優先度が低かったのですが、お客様のスケジュール感を鑑みて、外部の多言語翻訳対応ツールとの連携および導入を検討しました。
多言語翻訳対応ツールの選定は、
提供している業者をいくつか探し、こちらのシステムでやりたいことをその業者の方に説明したうえで見積を出してもらい、金額感と機能的なメリット/デメリットを比較する...
といったように、ある程度の期間と労力をかけておこなっていました。
しかし、よくよくお客様にヒアリングをかけたところ、英語表示さえできていればよい(日本語⇄英語の切り替えも不要)上に、英語表示必須な画面は数画面のみということでした。
その範囲の機能対応であれば、画面上の文言のディクショナリ化(=お客様がマスタ名称の文言を自由に変更できるようにする)で十分対応ができそうだということになり、その方針で進めることに落ち着きました。
結局、外部の多言語翻訳対応ツールは不要となり、他部署の関係者や他社の外部翻訳ツール営業担当の方など、多くの人の工数を無駄にしてしまいました。

手戻りや無駄な工数が発生しないように、お客様が本当は何を必要としているのかを洞察したいと思っても、私たちが考慮できる範囲には限界があります。
お客様に言われたことを真に受けるのではなく、何度もヒアリングを重ねたり、(最初は動かなくてもよいので)モックを作ってお客様に見てもらったりして、小さな失敗を高速で回すようにすることが、お客様が本当は何を必要としているのかを洞察する1番の近道なのだと改めて感じました。

プロダクト全体が見えない → 「視座を高める」

今まで書いたような失敗を重ね、"自分が担当しているドメインに関しては"今後の方向性やユーザーが必要としている機能をある程度深く考えられるようになり、ドメインの開発ロードマップを作成して今後の開発方針の指針とすることもできました。
しかし、自プロダクトは業務網羅性が高く、他にもさまざまなドメイン(およびそれに紐づく機能)が存在していました。
そんな自プロダクトにおいて、1人の開発メンバー/1ドメインの担当者という立ち位置でドメインをまたいだ機能開発・基盤拡張プロダクトとしての優先順位を考えていくことは限界がありました。

ここで、この項のタイトルの視座とはなんぞや、という話ですが、一言で言うと当事者意識のスコープということになるかと思います。以下の記事が参考になりました。
https://note.com/kgmyshin/n/ndbed1f3496a1
記事内では視座をx,y軸にプロットして図式化するという試みをおこなっています。
その図において、当時の自分は個人と担当ドメインに関しては当事者意識をもち解決策を実行できていたので、次にプロダクト全体(そして、→事業全体→会社全体→業界→社会...)へとスコープを広げていかなければならないと気付かされました。[5]

そこで、今まで自分が深くは知らなかった他のドメインについても、興味を持ってプロダクトを触って有識者に質問したりドメインの一般知識を調べてみたりして、少しでもキャッチアップするよう心がけました。
そうしているうちにプロダクト全体を俯瞰して見えるようになってきて、自プロダクトの強みや弱み、ユーザーが喜んでいるところや困っているところが客観視できるようになってきました。(この頃から、他社の競合プロダクトの特徴や、業務的に連携できそうな周辺ソリューションに対して興味を持って調べるようになりました。)
そこからはこのプロダクトはどういう人のどういった課題を解決するものなのかというPdM(プロダクトマネージャー)としての視座を意識して、どの機能開発に取り組むかを決めるようになりました。

また、プロダクト事業を収益的にどう成り立たせるかという事業責任者としての視座も途中から意識するようになりました。
こちらの視座についてはあまり自分は経験が乏しくまだ仕事に具体的に活かせるようなレベルではありませんが、自プロダクトではどれくらい売上がある一方で原価がどれだけかかっているから収支をどうやって改善させていこう、といったことを少しは考えられるようになりました。企業によってはエンジニアがこういった収支の部分を気にする必要がないこともあるかもしれませんが、プロダクトの開発と提供を継続していくためには欠かせない観点であるので、今後も強く意識していきたいと思います。

優先順位が決められない → 「個別最適より全体最適」

これまでの例は同じ機能やサービス内の話なので比較がしやすかったですが、実際の現場ではもっと複雑性の高い問題が跳梁跋扈しています。
これらの問題は、開発メンバー、経営層、お客様などのそれぞれの立場からそれぞれイシュー度が判断されて、やるべきことリストに挙がってくる場合があります。

(例)
開発メンバーA:「基盤のこの部分が負債になっているので早く改修したい」
開発メンバーB:「自分が担当のこの画面のパフォーマンスが悪いので向上させたい」
経営層 :「不具合が多いので、全社としてプロダクト品質を向上させる施策を打ちたい」
お客様 :「業務に手間がかかっているから早くこの機能をリリースしてほしい」

それぞれの立場から自分が見える範囲で個別最適化して導き出した"やるべきこと"は、どれも大事で優先度が高いように見えてしまいます。
しかし、つぎ込むことができるリソースは限られています

そのため、自プロダクトとしてやるべきことの優先度を一本化する必要がありました。これがプロダクトバックログになります。(ときには全社としてOKRなどで掲げて、プロダクトをまたいで協力体制を組む必要があることもあるでしょう。)
PdMが今もっともすべきことは何かを判断し、優先順位づけをします。そして、なぜそういった順位づけになったのかを関係者全員が納得できるように説明する必要があります。
そうすることで、開発メンバーが非協力的になる/経営層やお客様から理解が得られない機会が減り、より建設的な話し合いができるようになるかと思います。(機能Aの開発を優先する代わりに、機能Bはリリースを先延ばしする、などの判断・調整が可能に)
その上、プロダクトにとって今もっともすべきことは何かを適切に判断し改善を重ねていくことで、開発スピードが向上したりお客様に提供できる価値が増大させることができます。

1人でできることには限界がある → 「個人ではなくチームで」

プロダクトとしてやるべきことが徐々に見えてきて、その問題を解決したいと手を挙げるようになりました。
1人でも完結できるような、一つの機能やドメインにとどまる範囲の問題は解決できるようになりました。しかし、プロダクト基盤の改修や全ドメインに影響のある機能追加など、問題の難易度や複雑性が増すにつれて、影響範囲やステークホルダーも増えてくるため、1人で解決することはかなり難しくなっていました。

例えば、
スカンクワークとして、チーム全体の生産性向上のために自プロダクトに新たな開発基盤を1人で開発しようとしました。
構想から基本設計までは1人でもなんとか進められました。しかし、詳細設計や実装のフェーズになってくると、1人でぐるぐる考えてしまったり、1人でモチベーションを維持するのが大変だったりと、個人で進めていることに起因する理由で進捗が悪くなり、途中で頓挫してしまいました。(もちろん通常業務が忙しくて時間が取れないという要因もありましたが)
反対に、
自プロダクトのアーキテクチャ改善をおこなった際は、自分ともう1人のメンバーの2人を核として、PdMやインフラ担当者なども巻き込んで複数人で動いてました。
この取り組み自体は影響範囲がかなり広く難易度が高かったのですが、こうしてチームで動いていた際の自分が困ってもみんなに相談でき、誰かしらが建設的な意見を出してくれるという状況がタスクを進捗させる最も大きな理由となりました。
他にも、基本チームで動いて常に情報を共有しておくと何かあったときに前提を説明する必要がなく議論がしやすかったり、自分のタスクが溢れているときに他のメンバーが巻き取ってくれるなど、良い効果がたくさんありました。
結果としてアーキテクチャ改善は長い時間がかかりましたが無事リリースまで持っていくことができました。

開発手法としてペアプロやモブプロなどがあるように、個人ではなくチームで課題に取り組むことで良い効果が生まれるものは多いです。[6]
自分個人が成果を上げることではなく、チームとしての成果の最大化を目指すことが結果的にもっともプロダクトを成長させるのだなと実感しました。

仕事に意味が見出せない → 「プロダクトの意義を明文化」

プロダクト全体の成長に目を向けられるようになりましたが、より良いプロダクトにしていくにはどうするかを日々考えるにあたって、ずっと心に引っかかっていたことがありました。
それは"視座を高める"の項で述べたこのプロダクトはどういう人のどういった課題を解決するものなのかというプロダクトの意義をチームとして明文化できていないということでした。
これについて自分が懸念したのは以下のような点です。

  • メンバーは自プロダクトを開発・学習していく中で各々で意義を考えていく雰囲気になっており、それでは結局思い描くものがブレてしまうこと
  • 日々差し迫るタスクをこなしていく中で、今やっているタスクは果たして何のためにやっているのかがわからなくなること

そこで、プロダクトの意義を明文化して再確認するために、自プロダクトのMission(=果たすべき使命)とそれに伴ってチームのVision(=理想的な姿)とValue(=共通の価値観・指針)を定義することにしました。
自分が主導で趣旨の説明や各メンバーからの案の募集を行い、PdMやEM(エンジニアリングマネージャー)などと話し合いながら最終決定まで持っていきました。
こうしてプロダクトとしてはじめてMissionを定義し明文化したことで、自分たちがなんのために目の前のタスクをこなしているのか、本当にやらなければならないことは何かを再認識するきっかけが生まれました。

おわりに

ここには書ききれないほど他にもたくさん失敗してきましたが、周りの方々の協力やサポートのおかげで5年間やってくることができました。
エンジニアになりたてで、同じようなことで悩んでいる方やこれから悩むであろう方の少しでも参考になれば幸いです。
自分もできないことだらけでまだまだ学ばなければならないことがたくさんありますが、1人のエンジニアとして少しでもITの力で世の中を良くしていけたらなと思っています。
まとまりのない文章でしたが、最後までお読みいただきありがとうございました。

脚注
  1. 守破離に関して参考になった記事です。
    → 守破離を意識すると今よりずっと成長しやすくなる ↩︎

  2. 工数見積もり・スケジューリングに関しては以下の記事が参考になりました。
    → 不安とストレスから解放される見積りとスケジュール方法 ↩︎

  3. 開発において、便利なツールやIDEを利用したり、ライブラリが充実しているおかげで少ない実装で済むプログラミング言語を採択するなども、同じようなことだと認識しています。 ↩︎

  4. エンジニアは、仕事をすればするほど仕事が効率化されるはずだという話です。
    → プログラマが知るべき97のこと - ハードワークは報われない ↩︎

  5. 視座(視点)の上げ方に関して参考になった記事です。
    → 視点の上げ方、事業責任者や経営者に素早くなるには ↩︎

  6. 仲間がいるって心強いですよね。
    → プログラマが知るべき97のこと - 1人より2人 ↩︎

Discussion