こんにちは。Findy Freelanceの開発チームでエンジニアをしている2boです。
この記事では私が開発生産性を上げるために開発をする前に考えていることについて書きます。 ここで「開発をする前」というのは次のようなタイミングを指します。
- PdMなどから新規施策の仕様について相談を受けたとき
- 起票された開発Issueを最初に確認するとき
- 自分がIssueを作成するとき
なぜこのタイミングで考えるかというと、開発を進める上での方向性を間違える可能性を減らし後から軌道修正をしやすくするためです。
なおこの記事においては、開発生産性を「開発成果物の提供価値を投入リソースで割ったもの」とします。
いくら頑張って開発をしても、そもそもやるべきことの方向性を大きく間違えると提供価値が0に近づくため開発生産性が低下します。 特に開発が高速なチームで方向性を誤ると高速に間違った方向へ進んでしまうことになります。 そのような事態を避け、提供価値を少しでも上げるために考えていることを記します。
なぜ、いつ、だれがつかうか?
大前提にはなるのですが、まずは以下を考えます。
- なぜ:なぜその機能が必要なのか?ユーザーはなぜこの機能をつかうのか?
- いつ:いつその機能を使うのか?そのときユーザーはどういう状況にいるのか?
- だれ:どういう属性のユーザーか?ユーザーが社内にいる場合、どの部署/役割の人か?
これらの情報はありがたいことにPdMから普段提供してもらえています。しかしながら自分でも考えるようにしています。 エンジニアの視点からも考えることで、それを実現するための別の形の機能やアプローチが良いのではないかと提案できることがあります。
たとえ提案が採用されなかったとしても現行案の妥当性を確認できるため、方向性を間違える可能性を減らすことができると考えています。
開発する必要があるか?しなくて済む方法はないか?
提供価値を極力変えないまま、投入リソースを減らせるアプローチがないか次のことを考えます。
- 既に同じ機能が存在するか、または全く同じではないものの実質的に同じ提供価値を持つ機能があるか?
- 既存の機能を利用、または組み合わせて実現できるか?
- 外部サービスやライブラリをつかうことで実現できるか?
例えば、画面Aで情報の表示追加を要望された際、その情報をすでに表示している画面Bがあるため、画面Aへの直接追加ではなく、画面Bへのリンクを設けるだけで十分というケースがあったりします。
このように要望機能そのままでなくても必要十分をみたせば問題ないというケースでは、開発リソースを減らせることがあります。
シンプルにできないか?
機能が複雑になるとその後のメンテナンスや改修の工数が増加したり、作り直しが発生したりしてトータルで見ると生産性が落ちるということが起きがちです。
そのため次のことを考えます。
- 複数の関連性のない異なる目的を担う機能になっていないか?
- その場凌ぎでワークフローや処理の分岐を増やすことになっていないか、またはそれらを極力減らして開発できないか?
- 過度に自動化、抽象化することでなにをしているかわからなくなったり、イレギュラーケースに対応しづらくなっていないか?
私は過去にシンプルさよりもリードタイムを優先して機能追加をしたことがあります。その時は本来異なる目的をもつ既存機能に付け足す形で機能追加をしました。
最初のリリースまでのリードタイムは短縮できましたが、処理の分岐とデータのパターンが増えてメンテナンスとデータ集計がしづらくなり、結局は一から作り直すことになりました。 トータルで考えると最初からシンプルに別の機能として設計/開発をしたほうがよかったと考えています。その反省も踏まえての内容になります。
ただし、特にベンチャー企業においてはどうしてもリリースまでのリードタイムを短くしなければならない状況もあると思います。 そのため完全に否定できることでもないですが、単にそのほうが楽だからという理由ではやらない方がよいと考えています。
リリースを分割できないか?
ユーザーへの価値提供を考えて立案された施策や機能が、本当に有効かどうかは実際に提供してみないとわかりません。 また、大きな施策の場合は必須なものと必須ではないがあれば嬉しいというものが混在しがちだと考えています。 それらすべての内容をつくってからリリースする場合、期待通りの結果が得られなかったときに投入した開発リソースを無駄にしてしまう可能性があります。
これを避けるため、今回の開発で一番実現したいことはなにか?を考えて、もっとも重要なものから段階的にリリースすることを考えます。 いわゆるMVP(Minimum Viable Product)を開発ごとに考えるようなイメージです。
次のメリットがあると考えています。
- ユーザーに素早く価値提供ができる
- 効果やユーザーのフィードバックを早く得られる
- 結果が素早く得られるため、軌道修正や撤退の判断が早期にできる
- リリースあたり開発ボリュームを減らせるため見積もりのブレを減らせる
エンジニアのモチベーションの観点からも、早期にリリースすることで開発者のモチベーション向上につながりやすく、すべて作り込んで無駄になった場合のモチベーション低下も回避しやすいと考えています。
実例の紹介
ここからはこれまで紹介した考え方を実際に活かした「請求フローのシステム化」プロジェクトの事例を紹介します。
プロジェクトの概要
Findy Freelanceではユーザーの稼働後サポートとして請求書の作成代行と業務委託報酬の代理徴収を行っています。 そのため、ユーザー個々の稼働状況を確認し、内容に応じて請求書を作成して企業に送信する必要があります。
これらの作業の多くは手作業で行われていました。サービス利用者の拡大に伴い運用の限界が見えたため、請求フローをシステム化するプロジェクトが立ち上がりました。
請求フローの理解
私は開発リーダーとしてプロジェクトを途中から引き継ぎました。その時点で請求業務のドメイン知識がほとんどありませんでした。そのためPdMにヒアリングしながら請求フローの図を作成し、どの役割の人がどのタイミングで何をするのかを把握しました。つまり「なぜ、いつ、だれが?」の観点を確認しました。
情報を整理することでエンジニアユーザー、企業担当者、社内の営業担当者および経理など多くのステークホルダーが関与しているとわかりました。以後の開発で各々の視点を意識でき、先を見据えながら起案時よりもさらに価値のある仕様に繋げることができました。
設計の見直しによるシンプル化
次に、設計の見直しを行いました。プロジェクト引き継ぎ前は、手作業で管理されていた情報をそのままデータベースに移す形で設計が進んでいました。
例として、Findy Freelanceの契約スキーム上「企業とファインディ間の契約条件」と「ユーザーと企業間の契約条件」の2種類の契約情報が必要です。 当初はこれらを1つのテーブルで管理する設計でしたが、本来は別の情報であり、それぞれの契約変更のタイミングも異なるため、別のテーブルで管理することにしました。
これによりテーブルとモデルクラスの役割が明確になり、シンプルになりました。 また、2種類の契約情報がそれぞれいつ変更されたのかも管理できるようになりました。 設計の見直しには時間がかかりましたが、その後の改修や運用コストを考慮すると、見直して良かったと考えています。
スコープの決定とリリースの分割
プロジェクト引き継ぎ時、システム化に必須な機能と便利な機能がIssueに混在していました。 せっかくシステム化するならと多くの要望が積み上がっていましたが、スコープが不明確でした。
そのため、PdMを中心に関係者と協議してスコープを決めました。 早期の運用開始を目指し、必須機能のみを最初にリリースしました。例えば、次の機能は最初のリリースから除外しました。
- 社内管理画面の利便性向上
- ダッシュボードの作成(初回リリースではBigQueryからのデータ参照で代替)
- ユーザーがログインページから報告した稼働時間の確認(報告時にユーザーへメール送信しているため)
これらの機能は実運用後に必要性を再検討することにしました。スコープを決定し、リリースを分けることで運用開始までのリードタイムを短縮しました。 また、実運用をしたことで発覚した必要となる機能や改修があり、最初からすべて作りこまなくてよかったと考えています。
終わりに
以上が開発をする前に私が考えていることとその実例です。誰かの参考になれば幸いです。 ここに書いてあるようなことは普段から考えているという方も多いのではと思います。 読んでくださった方々が開発に際して考えていることなど是非コメントをいただけると嬉しいです。
また、ファインディではエンジニア領域のプロダクトの開発をするため、開発エンジニアが提供価値を考えるにあたり自然とユーザーの視点にたって考えることがしやすい環境であると感じています。 エンジニアへの価値提供に少しでも興味を持っていただけた方は、ぜひカジュアル面談のお申し込みをお待ちしております。
ファインディの採用情報はこちら↓
また、ファインディの開発メンバーが登壇するイベントを4/24(水)12:00~13:00で実施します! 開発生産性や開発のパフォーマンス向上にご興味ある方はconnpassページより是非お申し込みください! developer-productivity-engineering.connpass.com