Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

内製化をすすめる知人へのアドバイス

ソフトウェアエンジニアとしての働き方を探求してきた経験と、駐在員として文化の狭間でうろちょろしてきた経験、OSSエンジニアとして多数の多様な人材と交流してきた経験をもとに、果敢にも内製化に挑戦する知人へのアドバイスを気持ちまとめます。

前提

  • 主な利用技術にはJavaSpring Framework)やTypeScriptを想定
    • FaaSを始めとしたManaged Serviceは(いまのところ)積極採用しない構え
  • Digital Transformationを推し進める一環としての内製化に、エンジニアリングの観点から挑む方を読み手として想定
    • 内製化のターゲットは決まっているか心当たりがある状態
    • 既存の開発チームはほぼ無い想定

1. チームビルディング

1.1. スーツとギークの対立を避ける

我々が若かった頃は"スーツ"と"ギーク"の対立を煽る風潮にありました。Rockstar Engineerという、ひとりで27倍の生産性を持つエンジニアを称賛する動きもありました。Being Geekという本の表紙がまさに象徴的です。

それから時は流れ、ギークとスーツは消えました。チームマネジメントが再評価され、Rockstarよりも多様性が重視され、Stallmanが批判され、Linusが変わりました。我々は生産性27倍のSPOFをありがたがることをやめ、ソフトウェアエンジニアリングを組織に適用し業務効率を高め、サイロを克服しドメインを深く理解することによってビジネスを加速化することが求められるようになりました。組織にとって選択肢でしかなかったソフトウェアエンジニアリングは、Lean Software Developmentの確立や端末の市民への普及によって、すべてのビジネスに溶け込んでいます。

現代においてDDDやプロジェクトマネジメント、品質管理やサブスクリプションに関する本を手に取ると何が書いてあるでしょうか。科学的に仮設を検証し高速に市場を創出するための手法として、いかにビジネスとテクノロジーを融合するかという一点に関心が割かれています:

  • ドメインに注力することでビジネスの専門家とソフトウェアエンジニアリングの専門家が同じ用語で議論できるようになり、またソフトウェアをビジネスに追随させやすい状態を比較的保ちやすいことが知られるようになりました。
  • Project Managerはプロジェクトマネジメント手法としてAgileを学ぶことを求められています。
  • 品質とスピードがトレードオフではないことも広く知られ、スピードのために品質に関心を払うことがQAだけではなくProject Managerや経営層の関心事になりました。
  • 多くの企業がサブスクリプションに移行しているのは、収入の予測可能性が高まることに加え、顧客とのつながりを確保しテクノロジーを通じて多様な顧客を理解するための役割を期待しているところもあるようです。

しかし、Digital Transformationのための開発組織を構築する際は、かつての対立が再現されやすいような気がします。 特に"ギーク"が"エイリアン"として振る舞い"スーツ"がそれを"受容"する……という空気を作ってしまうと容易にハマります。

無用な対立を避ける意味で最も良いのは、「ビジネスとテクノロジーが融合する重要性」という内製化の背景を経営層が理解することです。そのきっかけ作りとして私はソフトウェア・ファーストを経営に読むことを勧めたりしていますが、打率はあまり高くない印象です。たぶん長すぎるんでしょう。

読者(ソフトウェアエンジニアリングの責任者)がビジネスの文脈を理解できている場合は、経営との対話を通じて少しずつ意識を変えていくことも効果的かもしれません。
このとき、相手は内製化の背景をまだ共有できていない、ビジネスのスピードを高める必要性を理解していないということを意識する必要があります。相手の語彙で対話し、相手にその必要性を再発見させなければなりません。でもこういう誘導する話し方って、焦っているときほど難しくなるんですよね。他社事例をストックしたり、スピードが出せていないことによる機会損失を試算したりと、普段から道具を収集しておくと助けになります。また話している文の主語を省略せず、常に明確にしましょう。これだけで誤解を避け、相互理解を進められる場合がけっこうあります。

1.2. 目指すアウトカムについて開発チーム内外で合意し文書化する

経営側の意識を変えにくい場合でも、内製化をする理由・テクノロジーに期待するアウトカムを議論し、文書として共有すると良いです。明確な目的は今後のコミュニケーションに役立つでしょう。

アウトカムを明確にすることは、組織がテクノロジーを融合する重要性を理解する助けとなるだけではなく、ソフトウェアエンジニアがビジネスを理解する助けにも、ソフトウェアエンジニアが目先のノイズに囚われないための助けにもなります。この時点では定量的でなくても良いので、チームを越えた錦の御旗として使うに値する明瞭な目標を持つようにします。

1.3. Agileでなくとも構わないが、学習できる組織を目指す

アウトカムを明確にしたくても、そもそも目標や目的の明文化に抵抗がある組織もあります。その場合、その文化を変えることがDigital Transformationよりも重要な課題だと認識する必要があります。なぜなら、目標と目的の明文化は経験主義に立脚する今日のソフトウェア開発において頻出するからです。たとえば:

ここでのキーワードは「学習」です。Scrumやself-organizing team、組織論について学ぶと必ず出てくる言葉です。組織に人によって教えられる”正解”はなく、試行錯誤が必要です。我々がDigital Transformationを目指すのも、この試行錯誤のサイクルを速めたいからだったはずです。よって個人や組織が学習できる環境を作ることが求められます。

ではどうすればいいのか。中原淳氏の研究(2010年)によれば、職場で人が育つためには「業務支援」「内省支援」「精神支援」が必要だそうです。ソフトウェアエンジニアにとっては「OJTや技術教育」「1-on-1を通じた振り返りの促進」「日々のコミュニケーションで励まし褒める」ことになります。

目的が明確であれば、OJTの内容も、1-on-1で振り返る方向性も、褒めるポイントも明確になります。また失敗をした際に意味のあるPostmortemをすることもやりやすくなるでしょう。目標や目的を明文化し、個人と組織が学習できる組織を作ることを心がけましょう。

1.4. 専門職を設けるべきか

今回の想定事例のような新しいプロジェクトで、ビルドやテスト、運用について専門職を設けるべきでしょうか。個人的には否定的です。 人材の流動性が高く既存資産も多くない状況であれば、全員が開発から運用まですべてのプロセスに関わる方が開発高速化の恩恵を受けられるはずです。

ビルドスクリプトやパイプライン定義、プロビジョニング手順はファイルで定義してGitで管理するようにします。 これにより属人性を下げるだけでなく、変更内容がレビュー可能になり信頼性も向上します。

2. 技術選定

とりあえず↓に目を通すのがおすすめです:

qiita.com

その上でいくつか具体的な話を。

2.1. 目指したい「品質」の合意を作っておく

ビジネスの専門家はもちろん、ソフトウェアエンジニアにとっても「品質」の定義はゆらぎがちです。人によって違う定義を使っていたり、品質保証に幻想を抱いていたりすることもあります:

一応ISO/IEC 25010:2011でモデル化されているのでMECEに考えること自体はやりやすいのですが、全部重要に見えてきて「これローンチなんて何年も先になるのでは?」みたいなことにもなりがちです。もちろんそんなことはできないので、優先度をつけなければいけません。

今回の想定するケースでは、少ない資産で早急にプロダクトを作り検証を通じて学習し成果を出さなければならない状況のはずです。であれば、私としてはMaintainabilityを重視します。コードをどんどん書き、どんどん捨てられることが何よりも重要です。そのためにコードが疎結合であること、テスト可能であること、目が届き把握できることを優先します。

なおMaintainabilityは、今回の想定事例以外でも重要視されている認識を持っています。ビジネスなどの変化が速く、すぐに「最適」が変化するためです:

一方でPerformance EfficiencyやCompatibility、Usabilityは脇に置いても良いと考えます。MVPによって正しい仮説を掴むまでは、これらの判断をしようがないためです。Webアプリケーション開発のようにインストール先が管理下にある場合は、Portabilityも不要かもしれません。さすがにSecurityが低優先とは言いませんが、ある程度のリスクは受容する判断があってもいいでしょう。

2.2. ビルドパイプライン

パイプラインファーストを志向するべきです。ソフトウェアプロジェクトを始める際は、まずパイプラインを構築します。

Gitを使ったPull Request(PR)ベースでの開発をする場合は、デフォルトブランチへの直接pushを禁止し、ビルドを壊す変更が導入されない状態をパイプラインによって保ちます。

CIがあればPRは不要だとする意見もありますが、今回の想定では新設チームであることも鑑み、いきなりデフォルトブランチへのpushを解禁することは危険だと判断します。あと、あんまり直接pushを是とする組織は現状多くないと思うんですよね。長いもの(industry standard)に巻かれておくことは、組織外の資源を有効活用するためのひとつの知恵です。

なおビルドパイプラインがどうあるべきかは、以前ブログに書いてますのでご参考まで。

2.3. まずはテストケースから書く

先述の通り、品質としてはMaintainabilityを最優先にします。そのためには、まずテストケースから書き始める文化を醸成します。新機能開発にTDDを適用したり、バグ修正時にバグを単体テストで再現したりといったところから着手します。

このプロセスを不要あるいは非効率と主張された場合は、品質とスピードがトレードオフではないことを根気よく伝えていく必要があります。プロダクトが高速に変化・成長するためには、既存機能が壊れていないことを機械的に検証する手段である自動テストは非常に重要です。またテストケースから書くことには、目的や目標の明確化をチームに促す効果もあります。

なお勘違いしてほしくないのですが、作成したテストケースは削除して構いません。実装や要件が変わり、既存テストが不要と判断された時点で削除しましょう。不要なテストが多く残ることでビルドやデプロイのパイプラインが遅くなっては元も子もありません。もちろんテストの並列実行のような技術的な解決方法はありますが、不要なテストを実行する理由にはなりません。
一応テスティングフレームワークには実行をスキップする機能もありますが、あれを多用すると好ましいスキップと悪しきスキップとを判別するコストが上がるので、VCSを信じてサクッと消すのが吉です。*1

また自動テストケースがあれば手動テストが不要、というのもよくある勘違いです。テスト自動化の8原則にも書いてありますが、手動テストはなくなりません。手動テストすべきところにコストをかける手段として自動テストがある、くらいの理解がちょうどいいかもしれません。

2.4. プロジェクト固有ルールを作らない

コミットコメント、コードレビューのやり方、ラベルの扱い、ビルド用コマンドやリリースノートの書き方など、ソフトウェア開発にはオレオレルール策定のチャンスが多く潜んでいます。これらを早めに潰すことで、新しくプロジェクトに参入する人の参入障壁を減らし、特定プロジェクトでのみ行うべき配慮をなくすことができます。既存資産がなく人材の流動性が高くレベル感もあわせにくい状況では、これは大きな助けになるでしょう。

例えば以下のような、一般化され公開されている知見を流用します:

逆に個人の裁量を認める部分としては、エディタやOSがあります。これらの選択を自由にするための技術として、というか開発環境の差を最小化する技術として、以下のようなものがあります:

なお新しい手法をまず小さく試すために一部プロジェクトに適用する、というのはありです。堅苦しく”管理”することは本意ではありません。必要なのは検証中という状態をずるずると伸ばさないことで、これも前述の学習する組織の構築や目的の明確化によって達成可能です。

2.5. KubernetesとかService MeshとかMicroserviceとか、他にもなんかエッジなやつ

チームが小さいうちは考慮しないでいいです。こまめにデプロイしリリースできることが重要です。 将来的にチームが増え、チーム間の協力体制をどう築くか?が組織の関心事になってからで良いでしょう。

3. 忘れてはいけないこと

実行こそが最重要です。ぐだぐだと基礎や知見、歴史を語ることは必要かもしれませんが、実行だけが世界を変えます。

つーか「明瞭な目標を設定しよう」とか、言うだけならタダなんですよ。それを現実のものとするのに、一体どれだけの傾聴と対話と勉強と失敗と思い切りが必要なのかって話ですよ。頑張ってください。

まとめ

  • ビジネスの専門家とともに目的と目標を設定し、継続的に学習するチームを作る
  • 求めるアウトカムと品質について、チームと議論し共有する
  • パイプラインとテストを最初期に導入する
  • コードを書け、検証しろ、振り返りをしろ、実行がすべてだ

あわせて読みたい

いただいたフィードバック

学習できる組織とはそもそもAgileでは?という疑問に対して、Agileという用語を避けることでビジネスの専門家に受け入れやすくなることを期待していると返答したことに対していただいたフィードバック:

内製化そのものに関してはあんまり触れらてないのでその辺をもっと聞きたい、という意見への私の考え:

*1:この点ではLaunchableにはちょっと期待していまして、スキップすべきテストが自動的に選択される未来が一般化するのかもしれません。