近頃、Software Craftsmanship(ソフトウェア職人気質)がホットな話題になっている。しかし、Joshua Kerievsky氏は「コードは常にクリーンでなければならない!」というCraftsmanship精神に対して、「Sufficient Design(十分な設計)」と呼ぶ対抗するような考えを唱えている。Joshua氏が意味しているところを知るとともに、彼の考えについてBob Martin氏とRon Jeffries氏の意見を聞く。
Kerievsky氏は一連の「Sufficient Design」という考えについて、次のような問題から話を始めた。
あらゆる最新コードのソフトウェア設計品質はできるだけ高くあるべきだ、と主張するプログラマがいます。「クリーンなコードを書きなさい、さもなくば、あなたはソフトウェア職人ではない!」とね。
彼らは善かれと思って言っています。たいていの人は、かなりの技術的負債を抱えて、行き詰まった経験があるでしょう。
でも、結局のところ、こういうアドバイスには単純な経済の問題の考慮が欠けています。ユーザにとってほとんど価値のない、あるいは多少価値のあるコードを時間をかけて巧妙に書いても、時間とお金を無駄に費やすことになるのです。
実際にはエクセレントな設計である必要のないコードもあるのです。まだ実験レベルのコードであるときもあれば、企業アプリケーションの一機能であるときもあります。
Joshua氏は続けて、彼の開発チームが、アプリケーションのいわゆる「プラミングコード(plumbing code)」にある既知の設計の臭いを、そのままにしておくという判断を下したというエピソードについて語った。その臭いは、アプリケーションのすべてのAction具象クラスで "processWith" メソッドが継承され、戻り値をひとつにまとめているところにあった。その存在が判明してから何年も経っても、二度のリファクタリングに失敗しても、依然としてこのコードは残されたままだったが、チームの邪魔になることはなかったと言う。そして、この障害ではない問題をクリーンにするために時間を費やすのは、賢明なことではないと主張する。なぜなら、もっと重要な機能に費やせる時間を奪うことになるためだ。彼いわく、
プロダクトにとって重要な意味があるものには、高い設計品質が必要です。でも、そうでないなら、もっと低い設計品質でも構わないのです。
...
今やソフトウェア設計のコツとは、みんなに愛されてお金になるソフトウェアを作るために、個人やチームが設計のダイヤルを機能ごとにどれだけうまく調整できるかで定義されるのです。
ソフトウェア品質において、万能のアプローチというものはありません。
もしあなたが機能マニアで、ソフトウェア設計をほとんど考えずに次から次へとプロダクトに機能を追加しているなら、リリース4.0になる頃には技術的負債のせいで行き詰まるでしょう。
もしあなたが品質マニアなら、どれもこれも最後までやっているのはやりすぎです。
「Sufficient Design」とは、リーン(Lean)とクラフト(Craft)が出会うところにあるのです。
最近のSoftware Craftsmanship活動の主役として知られるBobおじさん(Bob Martin氏)はすばやくこの考えに反応した。そして、一部の人は驚くかもしれないと注意しながらも、最終的にはJoshua氏の考えを支持している。
私には、Joshua氏はまさに職人がやるべきことをやっているように見えます。彼はまさに職人が気にするべきことを気にしています。そして、職人がするべき現実的な判断を下しています。システムにある大きな混乱をそのままにして、急いで次の機能を実装したりはしていません。代わりに、彼は自分のコードに注意を払っていました。
Martin氏は少し時間をおいて、Joshua氏がほのめかしているように、職人は「完全にせよ、さもなくば破滅する!」と言っているのではないという立場を明らかにした。
職人は何よりもまず現実主義者なのです。非常に品質の高いコードを求めますが、完璧にするのに夢中になって、愚かな経済的トレードオフをしてしまうことはありません。
公平に、Ron Jeffries氏によるフォローアップも取り上げておいた方がよいだろう。彼はプログラミングの場をクリーンにしておくのに時間をかけるべきだと、声高に支持しているうちのひとりだ。彼のメッセージは基本的に2つに要約できる。ひとつは、設計上の負債は「今返すか、後で返すか」のゲームであるということ、もうひとつは、速く開発できるよう、かつ、改善できるよう努力すべきだということだ。
もし品質を甘くすることで速く開発できているなら、長期的には必ず品質のコストが高くつくことになるでしょう。
そこから抜けだして、これまでよりも改善できれば、品質を損なうことなく速く開発できます。私たちには改善が必要なのです。今日は改善をする日ではないかもしれません。今日は品質よりも実際にスピードが必要かもしれません。しかし、これは不吉な前兆です。
もし品質を甘くすることで速く開発できるなら、迅速に品質を達成する能力に改善の余地があるという明白な証拠です。
間もなく、Kerievsky氏は「Sufficient Design」に関する「パート2」(彼はまだ続きがあることをほのめかしている)を公開した。今回は、「Sufficient」は、実際のところ質が悪い場合もあることをはっきり述べている。彼はIndustrial Logic社における開発で経験したエピソードについて語っている。今回はあまりに「巨大なクラス」に関するもので、大きなクライアント向けにイーラーニング製品の「プレイリスト」機能を手早く実装するときにできてしまったものだ。
そのプレイリスト機能を1年使ってもらって利用データを分析したところ、次のようなことがわかりました。さて、私たちはプレイリスト機能に設計上の負債を負うだけの価値があるでしょうか?
- ユーザは確かにプレイリストを使っている。
- これまでにプレイリストに不平を言っているユーザはひとりもいない。
- ユーザはプロダクトの他の機能のように、プレイリストを絶賛してはいない。
- 販売時に、将来クライアントになる人たちは、プレイリストが特定のトピックスのための時間効率のよい学習手順を提供すると聞いて喜んでいる。
ありませんよね。
以下が理由です。プレイリストは最大のクライアントを喜ばせるために投げ込まれた「アクセサリ」なのです。
- 新規の動作がないため — 去年一年間、もとのプレイリスト機能の動作を追加したり変更しませんでした。
- コードに変更がないため — 去年一年間、私たちがやったのは UserLibrary(プレイリストにおける設計上の負債が主にあるところ)を少し変更しただけです。この変更はプレイリストとは関係ありませんでした。
- 問題が隔離されているため — 私たちがプレイリストでやった質の悪い設計は隔離されています。去年、これが新機能開発の障害となることはありませんでした。
この機能は便利ですが、プロダクトを開発する上でのクリティカルパスではありません。
巨大なクラスや複雑な条件文といったプレイリストにあるコードの臭いのせいで、私たちのスピードが落ちることはありませんでした。
そして、品質をどう管理するか、以下が私たちの理解です。
もし、もっと洗練されたプレイリスト機能をユーザに提供すると決まれば、新しく機能を進化させる前に、私たちは喜んで設計の負債を支払います。
Joshua氏は、将来必要になったときに取り組んでも困るようなことはないと説明する。彼のチームにはTDDのスキルと規律があり、単に低い技術がふさわしいときと高い技術へとダイヤルを回す必要があるときを理解し、対応しているだけのことだと言う。彼は次のようにまとめている。
では、私たちは1年前のプレイリストのコードに満足しているかって?
ええ、あの時、必要以上にプレイリストにお金をかけなかったことに満足しています。
設計をクリーンにしたいとは思ってますが、そのタイミングが来るまで待ちます。
それが「Sufficient Design」なのです。
あなたはどう思うだろうか? Joshua氏のアドバイスは一般的に受け入れられるだろうか? 同じようなアプローチを自分のプロジェクトでやってみて成功したことがあるだろうか? あるいは、無惨にも失敗しただろうか? さらに議論するには、他に何を検討する必要があるだろうか?