タオルケット体操

サツバツいんたーねっとでゲームとかガジェットのレビューとかをします

雑な仕事のほうが早くプロジェクトが完成するという考え方は根本からして完全に間違っている

今でこそ「技術的負債」みたいなワードがプログラマーの共通認識として取り入れられているので、技術者同士であれば話が通りやすいんだけども、それでもいざ負債の返済をやろうという段になると「そんな暇はない」というような返事が返ってくることが多い。そもそもそういう話が通らない人もいて、そういう人は「いいからチャッチャと次の機能を書いて終わらせろよ」みたいな空気になりがちなようにおもう。

なぜ根本から間違っているのか

そもそも雑な仕事だと中規模程度のコードベースでも崩壊しかねない。雑がすぎるとそもそもプロジェクトは完成しないのだ。現実にヘーシャも、進行の雑がすぎた結果として進捗が終わり、生贄に捧げられた人も精神が終わり、関わる人はみな会社をやめてプロジェクトは永遠に宙ぶらりんですよみたいなものがゴロゴロ存在している。

また、丁寧であることが質に直結するというのも常にtrueではない。
当たり前だが質の高いものは、良いコンセプトがあり、腕の良いプログラマーがいて、その人が裁量を存分にふるえる状況と余裕(時間含む)があって完成する。どれかが欠けても無理ではないが、全部が欠けていてはまず不可能だろう。
また、完成しないものは質もクソもない。無だ。リリース時期をおさえなければいけないようなプロジェクトで、そのポイントに間に合わないようなものもビジネス的にいえば無だろう。

コードの品質と完成までの速度は相反する概念ではない。それらはサービスの質を支える要素で、お互いが混ざり合っている。
よく作られたコードは修正や機能の追加がしやすい。これはユーザビリティそのものに関わる問題だし、クソコードと比べると開発速度も早い
提供の速度も重要で、競合のいないスペースにねじ込むというビジネス上の問題もあるが、例えば今から数年かけて最高のJavaScriptコードを書いたところで、数年後にはNodeのバージョンは10くらいあがり、ECMAScriptの仕様も膨れ上がっていることになるだろう。今現在の最高は数年後の最高ではない。それなりの開発速度でリリースポイントを作り、進行方向を調整していくことはコードの質を保つことと不可分だ。

テストやリファクタリングに対して、「そんなことをする暇はない」が口癖のチームで働いていたこともあったが、たった一つのテキストボックスの値のバリデーションがうまくいかない、というバグを修正するのに数日かかる始末だった。そして予想通り、修正のたびにデグレが発生するし、それをある程度未然に防いでくれるはずの自動テストも存在しない。
数ヶ月ほどかけてまずいところ*1の中でもクリティカルな部分を修正していった結果、かなりマシになった。少なくとも、簡単な修正や機能に数日かかるようなことは減ったので、数ヶ月の投資はペイできた。
これは僕のあくまで個人的な体験だが、質を向上させた結果として開発速度が上がった例で、きっと同じような経験をした人は何人もいるだろう。

逆の失敗談もある。まぁ今の話だが。
無茶振りな納期を迫られた結果、今回は仕方ない(何が仕方ないのかは不明)からテストは書かないでおこう。コードの綺麗さもある程度犠牲にしちゃおうという話になった。
その場しのぎで書かれたコードは、後で必ず修正を迫られる。設計が汚いと、機能の追加や修正は恐ろしく繊細な作業になってしまう。追加や修正の作業は、必ず確認が必要だ。確認作業(手動テスト)は最終的には必須だが、恐ろしく時間を食う。

結果として、今は自動テストを書き始めている。そして、自動テストを書くためにバラバラの手続きで書かれたコードをテスト可能なオブジェクトへと修正している。
これは納期を鑑みるとかなり危うい作業だが、これからの数ヶ月を考えると開発速度を出すために必要な足止めだと僕は考えている。限度はあるが。

そもそも論になるが、プログラマーが能力以上の速度や質を出すことは不可能だ。それを小手先の根性でなんとかしようなどと考え、抜いてはいけない手を抜くから炎上が酷くなる。それだけのことだとおもう。もし、どうしても納期を優先しなければならない事情がある場合は、雑な仕事をするまえに仕様を削ろう。それは手を抜くのはまた違う話だ。
技術的負債というのは、人類がその時のベストを尽くして現実と戦った結果に生じるもので、人類が完璧な存在ではない以上宿命的に生まれるものなんだけど、少なくともいい加減な仕事を許容する言い訳にそれを使うのはいけないことだとおもう。

以上、たぶんに経験から抽出されているところがあるので見苦しいかもしれないが、僕はこれを真実だと考える。


以下蛇足

以下で書くことは、かなりまとまりのない内容になる。上記の主張を補強したりするような蛇足だ。

プロトタイプへの誤解

「プロトタイプを作る」という言葉も誤解している人がいて、そういう人はプロトタイプを「適当に作った第一段階」という捉え方をしている。
まぁそれもあながち間違いではないんだけど、プロトタイプはどちらかといえば実際に動くモックアップを作ることで各人の考えている仕様の齟齬を洗い出すことに意義がある。いわば要件定義の一部だ。
これを誤解してる人は、「プロトタイプは雑に作るから早く完成して、そのプロトタイプに適当に肉づけすればプロジェクトはインスタントに終わる」みたいなことを言い出したりする。これは営業職の人とかに多い気もするが、技術部門の人でも割とこう考えている人は多いと思う。
プロトタイプが(比較的)早くできあがるのは雑だからじゃなくて、中核以外の機能を全て削るからだ。例えば認証のフローやセキュリティに関わる部分は省かれることが多い、しかしそれらは正規リリースには絶対必要で、かつ中核のロジックにも深く関わることが多い部分だ。とても工数がかかる。

プログラミング的にいうプロトタイプは、どちらかといえば製品のエッセンスを抽出して作るモデルなので、表面的な動作は同じでも内部の仕組み的には本番リリースには向いていないということが往々にしてある。
なので、プロトタイプはリリースの直線上にあるαやβとはまた違った世界線にあるとおもったほうがいい(そのままαいけることもあるけど)。

コードの書き直し、テストの導入を嫌がる

プロトタイプをリリースした後で、「これはそのままでは使えないので新しく書き直し(もしくは設計を組み直し)ますね」とか、「テストを書いてなかったので一通り追加してからαいきます」みたいなことをいうとすごく嫌な顔をされる。言わなきゃいいんじゃないかというかもしれないが、同じプログラマーの中にも嫌がる人がたくさんいるんだから仕方ない。

設計のやりなおし*2、自動テストの導入は、いわば「丁寧な仕事」の部類に入るだろう。
対して、「プロトタイプに適当に肉づけしてちゃっちゃとαを出す」は「雑な仕事」の部類になるんだろう。

ここまで書くと、僕が前者を推奨したいんだという風に読み取れるかもしれないが、そうではない。

僕が言いたいのは、そもそも丁寧と雑をプロジェクト進行における対立概念にするなよということだ。

テストを書く暇なんてない vs テストを書かない暇なんてない

これはどちらの主張も真だとおもう。
ただし、大局的な視野でいえば「テストを書かない暇なんてない」が真だろう。

ではなぜ「書く暇なんてない」も真だと考えるのか。

どんな職業でもそうだが、プログラマーという職業は常に勉強が必要で、内容も多岐にわたる。
その中でも自動テストというものは比較的に学習負荷が高く、そして言語や環境によって勝手が違うことが多い*3のだ。そして、「なくてもなんとかなる」ものなのである。
経験年数の長いプログラマーでも単体テストを書いたことがない人というのはたくさんいる。そういう人が単体テストを書く場合、学習する時間も工数に含めないといけなくなる。それで「書く暇なんてない」という話になるのだ。
僕も単体テストの経験値がかなり低いので気持ちはよくわかる。テスト書くのはすげえ難しい。

単体テストが曲者なのは、ツールの使い方だけ覚えてもダメなことだ。
テスタビリティの高いコードを書いていなくてはならない。グローバルな状態を保ちまくる手続き型のコードに対して単体テストを行うのは全く意味がない。オブジェクト指向でも関数型でもかまわないが、テスト対象のコードがそもそも洗練されていないといけない。
野放図に状態をもたせたり、モジュール同士の依存性を適当にしてしまうというのは最早手癖のようなもので、これを修正するのは多大な苦労がかかる。
これもまた「テストを書く暇なんてない」 or 「単体テストなんて書いても意味がない(書けない)」という意見を生み出す原因だろう。

seleniumなどの結合テストのために使うツールにコーディング力の問題は発生しないが、今後はテストの実行時間が長いこと、環境の整備が大変だという問題が発生する。
一度構築と運用の経験を積んでいて、さらにプロビジョニングを自動化していたりすればここの負担は減るだろうが、テストを書かないチームにそこまでしている時間があるかどうかは怪しい。

コードは書くよりも(変更のために)読む時間のほうが長いこと、平均的なプロジェクト進行におけるテスト期間の長さを考えても、自動テストの存在は常に正義だろう。質が速度に貢献する。

そして、自動テストという行為の難易度について言及したが、質のための行為というのは常に作業するプログラマーに能力を要求してくる。
能力があがれば質と速度は共に向上する。

雑にやるとか、丁寧にやるとか、そういったレベルで物事を考えるのはやめよう。
そもそも時間を言い訳に雑な仕事をする人は、平時でも仕事が雑だ。雑だから手戻りがおおくてますます忙しくなる。卵か鶏かしらないが、能力のマックスとちゃんと向き合っていないとこういうことが起こりうる。

日常的に能力をあげる努力をして、普通に発揮してやればいい。ちゃんと成長していれば、普通にやっていてもちょっと前の自分より早く、良い仕事ができる。成長の調子がいいと昨日の自分を大きく上回ったりするし、それは成長の結果としてそうなっただけなので持続性がある。
結局どんな誤魔化しをしたって自分の能力以上の仕事はできないわけだし、そういう風に自分を育てていくのが結果的に楽な生き方だとおもう。

ちなみに僕は近頃あまり成長に投資していなかったので、やはり状況の楽さが足りていない気がする。
これは自業自得なのでもっと楽さを追求しないといけない気がする。ドラクエビルダーズもクリアしたことだし、そろそろ楽さを次のレベルにあげねばならないなという気持ちが高まっている。みんな楽にいきていこうな。

おしまい。

*1:Pythonなのにtabとspaceが混在しているのを修正するところからはじめた

*2:ちなみにここでいう設計は詳細設計とかいうエクセル製で生産するクソの山とは別物なので悪しからず

*3:RSpecダルいぞ