
海外赴任のあいだに、オフィスのテーブルを組み替えてもらったことがあります。
板の枚数、ねじの型番、どの板から先に入れるか。紙に書いて送ったら、そのとおりに組み上がった写真が届きました。ところが、天板と脚のあいだの間隔だけが、思っていたものと違います。
翌日、「もう少し詰めてほしい」と電話し、また写真が届く。まだ違う。3回目で、ようやく合いました。紙に書いたとおりのものは、1回で組み上がっています。書けなかった間隔だけが、電話3回ぶんかかりました。
ソフトウェアを海外の開発会社に発注して作ってもらう、オフショア開発を使う会社が増えてきました。国内で人を採用しても間に合わず、また、国内のエンジニアの品質を上回る先端技術の知見と単価の差も無視できないからです。
僕も、オフショア開発をやっていますが、最初はことごとく失敗しました。決めるべきことを全部書き切った設計書を渡し、そのとおりのものが上がってきたのに、そこから細かい直しが止まらなくなりました。いちばん小さかったのは、画面の余白の値を1箇所だけ書き換えるために、海外と1往復するというものでした。
先に一行だけ置きます。ここでいう往復とは、依頼を送り、返ってきた結果を確認するまでの一連のやり取りです。オフショア開発で効いてくるのは、時間あたりの単価ではなく、往復の回数です。 単価は契約で決まりますが、往復の回数は仕事の分け方で決まります。
この話に出てくる事業

大企業と僕の会社が組んで立ち上げた新規事業で、必要最小限の機能を備えた試作品(MVP)のひとつに、車の正規ディーラー(自動車メーカーが正式に認めた販売店)が使う、整備予約と入庫管理(車を工場へ受け入れる予定の管理)の画面があります。この画面を使うのはディーラーと工場で、僕の会社はそのシステムを開発する役割です。
受付のカウンターに立つのは、ディーラーの拠点あたり2名です。電話で「来週の土曜に車検をお願いしたい」とお客様に言われたら、その瞬間に、代車の空き、整備士の空き、部品の入荷を同時に見て、その場で日を決めます。整備士は8名。工場側で、その日に整備を受け入れる車の並びを見ています。
このシステムを、オフショア開発で作ることにしました。 国内の人手では、年度内にシステム開発が完了できる見込みがなかったからです。最初のリリース(利用者が使える状態にした版)を受付に置くところまでは、オフショア開発で進めました。そして、PoCを通じて、不満を抽出し、まとめて直す時が来ました。その直しに関する工程が、この話の舞台です。
今日は上記のPoC後の直し工程を通じて、オフショア開発に何を渡して、何を手元に残すか、という話をしていこうと思います。
前置きはさておき、本題に入ります。
① 教科書どおりに、設計書を書き切ってから発注した

オフショア開発の教科書に書いてあることは、はっきりしています。曖昧な仕様を渡さないこと。決めるべきことは先に決めておくこと。独立して進められる単位に割って渡すこと。 どれも、そのとおりだと思います。
だから、素直にやりました。ディーラーの受付担当者から出てきた不満を6件に整理し、その1件ずつがプログラムのどのファイルのどの行から来ているかを表にしました。
「代車の空きは、予約が確定した時点で押さえる」というような、迷いそうなディーラーからの要求仕様は全部そのタイミングで潰しています。詳細仕様を決めずに渡すものを1つも残さなかった結果、設計書は134行になりました。
そのうえで、6件の不満を、そのまま独立して進められる6件の作業に割りました。渡したのは作業の名前ではなく、触るファイル名と、そこで何をするかです。
上がってきたものは、仕様どおりでした。 6件の作業が全部、1日で返ってきています。予約一覧も、整備士側の一覧画面も、書いたとおりに動きました。
この日は、うまくいったと思っていました。
② そのとおりに上がってきたのに、直しが止まらなかった

翌日、拠点の受付カウンターで、実物の端末に入れて開きました。
ここから、直しが止まりませんでした。
その日のうちに入った直しは14件です。そのうち11件は設計書に書かれていないもので、実物を開いて初めて出ました。設計書に書けたことは1日で終わったのに、書けなかったことは、実物を開いたその日から出はじめました。
中身を書き出すと、次のようになります。「予約一覧の上端の余白をそろえてほしい」。「予約1件ぶんの枠の下の余白を12pxから24pxに」。「どちらか一方を選ぶ丸印で、選んでいないほうを白にしてほしい」。整備士側の一覧画面については、「実物で見ると余白が詰まって見える」という一言が返ってきました。
どれも、仕様どおりです。 設計書に、上端の余白をいくつにするとは書いていません。書いていないので、海外の開発会社が決めました。決めた値が、カウンターで見ると違っただけです。
ただ、実物を開いて初めて出た直しは、1回では終わりません。値を変え、実物に入れ、また開いて見る。見て決まるものは、見るたびに1往復ずつ増えていきます。
実物を開いたことが起点の直しは、最終的に16件になりました。1件につき最低1往復かかるので、海外とのやり取りが16回増えたということです。
③ 気づいたのは、直しの中身を行数で数えたときでした

回数だけなら、まだ「そういうものか」で終わったかもしれません。
引っかかったのは、1回の往復で何行動いたかを数えたときです。16件のうち、変更行数が少なかった4件は、4行、6行、8行、9行でした。挿入と削除を足した数です。
最初は、数え方を間違えたのかと思いました。設計書には134行を書いています。それに対して、往復1回で動いたコード(プログラムの記述)は4行です。
そこで、往復の回数と、1回あたりに動いた行数を並べ直しました。直しが小さくなっても、1件あたりの往復回数は減らず、1回の中身だけが小さくなっていきます。 大きい直しは最初の数件で終わり、あとは余白と色の値の調整だけが残ります。
ここで、渡し方ではなく、仕事の分け方が間違っていたのではないか、と思いはじめました。
④ 原因を1つに特定する

仕事の分け方がうまくいかなかった理由として思い当たることは、いくつもあります。設計書にどこまで細かく書くか、時差、言葉の壁、実物の端末を相手が持っていないこと。
ただ、原因を絞ると1つでした。
設計書に書けることを基準にして、仕事を分けたこと。
書けることは、全部書きました。画面の遷移(操作に応じて別の画面へ移る流れ)も、押したときに何が起きるかも、代車をいつ押さえるかも書けます。書けたものは、1回で終わっています。
一方で、文章に書けなかった仕様は、書面にできないままオフショア会社へ渡りました。 余白がいくつなら詰まって見えないか。丸印が白と灰色のどちらなら押せるように見えるか。カウンターで電話を持ったまま片手で操作したときに、指がどこに届くか。文章にした瞬間に、実物の前で確かめていたものとは別のものになるので、書けません。
つまり、文章に書けない仕様だけが、往復を生みます。そして僕は、その仕様を、海外の開発会社という、いちばん往復が高くつく場所に置きました。
⑤ 直したのは1箇所だけ

やったことは、余白を画面ごとに指定するのをやめただけです。
余白の値を、すべての画面が共通で見る1行にまとめて置きました。中身は4つの数字です。「上端24、かたまりとかたまりのあいだ24、見出しと中身のあいだ12、かたまりの中の要素どうし12」。この4つ以外の余白は、使わないと決めました。
決めたのは値ではなく、値を決める場所です。予約一覧も、代車の一覧も、整備士側の一覧画面も、余白は自分で持ちません。全部この1行を見に行きます。そして、この1行だけは、僕たちが手元で書き換えることにしました。
余白を使っている場所は18箇所ありますが、値を持っているのは、この1行だけです。カウンターで「詰まって見える」と言われたら、直すのも1行。往復1回で、3拠点の全画面が同時に動きます。
このときはまだ、名前のある考え方だとは知りませんでした。
⑥ あとで知った ── 分け方に、すでに名前がありました

しばらくして、『Team Topologies』というチームの組み方を扱った本を読み、手が止まりました。
そこでは、チームとチームのつなぎ方が、2つに分けて説明されています。ひとつは「working together for a defined period of time to discover new things」。期間を区切って一緒に手を動かし、まだ分かっていないことを見つけにいく形です。もうひとつは「one team provides and one team consumes something “as a Service”」。一方のチームが提供し、もう一方のチームが受け取るだけの形で、あいだの行き来はほとんど要りません。
つまり、探り合いが要るかどうかで、つなぎ方を変えるという話でした。余白の値は探り合いが必要な対象で、画面の遷移は必要のない対象です。僕が1行にまとめたのは、探り合いが必要な部分だけでした。まとめた結果、その部分だけが手元に戻り、探り合いが不要な部分は渡したままになっています。
拠点をまたぐ作業にかかる時間も、測られていました。Herbsleb と Mockus が、ソフトウェア工学の学術誌 IEEE Transactions on Software Engineering の29巻9号(2003年)に出した調査に、こうあります。「distributed work items appear to take about two and one-half times as long to complete as similar items where all the work is co-located」。拠点をまたいだ作業は、同じ場所で終わる作業の2.5倍の時間がかかる、と読めます。
しかも、遅くなる理由まで書いてありました。「distributed work items involve more people than comparable same-site work items」。拠点をまたぐと、同じ作業に関わる人数が増える、という説明です。同じ調査のアンケートには、自分の仕事について誰に連絡すればいいのかを探すのに時間を取られている、という設問も並んでいます。
余白を24にするために、誰に言えばいいのかを探す。その時間が、2.5倍の中身でした。
新しい理屈は、ひとつも要りませんでした。
⑦ 変えてみて、何が良くなって、何を失ったか

分け方を変えてから、手元で変わったことがあります。
余白と色に関する直しは、1回の往復で終わるようになりました。値が1箇所にあるので、カウンターで見て決め、その場で書き換えれば、3拠点の全画面が同時に変わります。海外の開発会社の手は、そのあいだ止まりません。
ただ、代償があります。3件書いておきます。
1件目。画面ごとの微調整ができなくなりました。 整備士側の一覧画面は、その日に入る車を横方向へ並べるので、本当は上端を24より詰めたいところです。それでも24にしています。4つの数字以外を使わないと決めたので、例外を作ると元に戻ります。
2件目。1行にまとめる作業そのものが、直しより大きくなりました。 余白を直すつもりが、余白を自前で持っていた場所を全部探して剥がす作業になっています。先に余白の値を1行にまとめていれば、払わずに済んだ手数でした。
3件目。手元の仕事が減りませんでした。 探り合いが要る部分を引き戻したので、その部分はずっとこちらに残ります。オフショア開発に出したのに、手が空くわけではない。空くのは、書けることを書き切ったぶんだけです。
⑧ 現場で分けるなら、この3つの問い

オフショア開発に何を渡して何を残すかを決めるとき、使っているのはこれだけです。
| 問い | はい | いいえ |
|---|---|---|
| 文章だけで、合っているか判定できるか | 渡してよい | 手元に残す。 見て決まるものは往復になる |
| 直しの中身が、数行で終わりそうか | 渡す前に、値を1箇所へ集めておく | そのまま渡してよい。1往復で動く範囲が、もともと大きい |
| 決める人が、実物の前に立っているか | 手元に残す | 渡してよい |
いちばん効くのは、2つ目の「直しの中身が、数行で終わりそうか」です。直しが数行で終わるものは、渡す前に1箇所へ集めておく。 集めておけば、往復の回数はそのままでも、1回で動く範囲が全部になります。集めていないと、4行の直しに1往復を払い続けます。
逆に、文章だけで合否が決まるものは、迷わず渡してよいと思います。代車を押さえる順番も、車検の期限が近い車を上に出す規則も、書けば決まります。書けるものは、距離があっても値段が上がりません。
この見方は、扱っているものには依存しません。整備予約でも、経費精算でも、在庫の一覧でも、同じ形で使えます。
⑨ この分け方が効き続ける理由
翻訳の精度が上がっても、時差を埋める道具が増えても、この分け方は変わらないと考えています。
道具で短くなるのは、1回の往復にかかる時間だけだからです。往復の回数そのものは、変わりません。回数を決めているのは通信の速さではなく、「見ないと決まらないものが、いくつ残っているか」です。
そして、見ないと決まらないものは、文章がうまくなっても減りません。減らせるのは、それを海外の開発会社に置くかどうかの一点です。だから、賢い道具が増えるほど、先に効いてくるのは仕事の分け方になります。
このあたりの分け方を実際の開発に落とす話は、AIプロダクト開発のページに整理しています。オフショア開発に何を渡すか決めかねている工程があれば、こちらからご相談ください。
実家のテーブルは、いまも3回目の間隔のまま立っています。あの間隔が正解だったのかは、正直よく分かりません。
以上です。