オブジェクト指向開発を理解した開発者に、設計書は不要
わたしのソフトウェア開発者としての経歴は10年程度。10年間、いろいろなものを作ったが、「設計書」と言えるもの、つまり「基本設計書」「詳細設計書」がある形でプログラム開発したことは一度もない。たぶん、これからもないかと思う。
「大したものを作っていないのでは」と、わたしのソフト開発者としての能力を疑う人が出てくるかもしれない。しかし、大企業で大勢の人に使われるようなシステム――規模にして数十年月のしっかりしたシステムを作ってきたことは事実である。ということで今回は、「設計書なしでかなりの規模のシステムを作る」ことに関するわたしなりの方法論を少し書いてみる。
オブジェクト指向は必須である。「設計書なしである程度の大きさのソフトウェアなんて作れるわけがない」と思っている人は、おそらくオブジェクト指向の何たるかが分かっていないのではないだろうか。オブジェクト指向さえ分かっていれば、設計書なんてなくとも大規模開発は可能なのだ。だが、オブジェクト指向が分かってない人に設計書なしで開発をやらせることは自殺行為。それは絶対やるべきではない。
「設計書が絶対必要」という人は、「設計書を書くことによって、最初に何を作るかがきれいにまとまる。実装が終わってからの修正、手戻りが少なくなる」と主張するだろう。後は、「設計書があることによって、大きな視点からのシステムのあるべき姿が明確になって実装しやすくなる」ということだろうか。
オブジェクト指向を分かっている人に、設計書なしで開発をやらせるときの流れを書いてみる。
まず、プログラマは作る対象である分野の専門知識について、いろいろな書籍を読んで習得する。当然それだけではシステムは作れない。その知識を前提に、要件定義者から要件を口頭で聞く。このとき、オブジェクト指向が分かっている開発者は複数のオブジェクトの相互作用として、システムが動作することを頭に思い浮かべながら、ヒアリングをする。専門用語がそのまま必要なクラスの1つになることもある。
ある程度要件を理解したところで、DBのテーブルの設計を始める。DBのテーブルだけは、作ってから変更を入れる必要があった時、工数が大きくなるので、ここはある程度の熟考が必要になる。その後、プログラミングを始める。頭の中に、複数のクラスを作り、それを1つひとつ実装していく。その際、それぞれのクラスを自動テストするプログラムを同時に作ることは必須だ。
そしてある程度できあがったところで、その時点の成果物を要件定義者に見せて意見を聞く。要件を完全に理解せずに始めた実装である。おそらく多くの修正依頼が出てくるだろう。オブジェクト指向の原則に基づいて開発していれば、その修正依頼に対応することは、たいてい簡単なのだ。
なぜ修正依頼に対応することが可能なのか、少し説明してみたい。オブジェクト指向の基本原則に、SRP(Single Responsible Principle)、つまり「各クラスモジュールの責務は1つだけ」というものがある。このおかげで、変更内容を分割し、分割した変更それぞれが1つひとつのクラス内に収まるようにして、少しずつ変更を入れていくことが可能になる。変更のたびに、あらかじめ作成している自動テストプログラムを走らせる。
「変更を入れると分岐がどんどん増えていき、プログラムの構造がどんどん複雑になる」と考える人もいるだろうが、「変更するときは、その前にリファクタすることを鉄則とする」ことによって防げる。つまり、変更を入れる前に、変更を入れやすくするように、プログラムの構造を変えるのだ。あるクラスが、その属性によって異なる振る舞いをすることが必要になった場合を考えてみよう。安易に条件文の追加で振る舞いのコードを切り替えるのではなく、属性により異なるクラスが使われるような実装に変え、それぞれのクラスが行う実際の振る舞いが異なるように実装する。修正を入れるごとにクラスがどんどん増えていくが、それは必要悪だ。ただし、最近の.NET開発では、WF(Work Flow)などで、処理の大きな流れをワークフローとして定義し、ワークフロー内の部分処理の切り替えを容易に行えるようにする開発や、 Dependency Injectionなどのパターンを使って振る舞いの切り替えを容易にする方法、関数に匿名メソッドを渡すような方法など、多くの方法が発達しており、クラスの増加を防ぐことが容易になってきている。
ところで、DBのテーブル設計の変更について。これはなるべく避けたいが、「完全に発生しない」という方針を貫き過ぎると、万が一テーブル設計変更の必要が生じたとしても、テーブルの変更をせずに切り抜けることになってしまい、かえって実装が複雑になってしまう。避けられないときは、あっさり変更するべきだ。ただし、その時の工数を減らすためには、やはりORMのツールの使用は不可欠である。LINQ to SQLレベルのORMのツールの使用は絶対必要だ。ADO.NET Entity Frameworkもしくは、Hibernateを使うべきだ。一般に、 SQL文は変更に弱い。なるべくSQL文を減らす実装に徹するべきだ。
ここに記述したような開発は、誰にでもできるものではない。プログラマから始まってSEになり、最終的にプロジェクトマネージャになるというような、日本で一般的なキャリアパスでは、こういうことができる開発者がなかなか育たない。よっぽどの天才でない限り、1人またはの少数のチームで1年以上の開発をした経験がないと、こういう開発はうまくできないだろう。大きなチームの中で、詳細設計書を渡されて大きなシステムの一部分を開発し、5年ぐらい経験したところでSE になり、実装から離れて設計書だけを書く立場になるような日本の一般的キャリアパスでは、だめということだ。
いま、日本の現場でデシジョンメイキングをしている人は、それが分からないわけだ。当然のことだ、できる人が周囲にいないわけだから。「結果的に設計書なしで開発などそれは趣味の開発だけだ」と主張し続け、日本の開発現場が変わることができない。
ところで、人を採用するときや採用した後、どうやってオブジェクト指向の理解度を測ることができるだろうか? 面接だけで、理解度を測る方法は、わたしにもわからない。一番確実な方法は、1人もしくは数人のプロジェクトで何年にもわたるような開発をしっかりとやってきた実績があるかどうかだと思う。大手SIの扱うプロジェクトは、たいていの場合大規模だろうから、その開発実績はあまりあてにならない。結局、面接で判定するのは難しいので、確実な方法は実際に開発させることだと思う。3カ月程度は契約社員として採用し、契約終了時に判定するという手段が無難な方法だろう。
最後に、注意事項。ここで書いたような開発、つまり要件定義書や基本設計書なしでの受託開発は、よっぽど小さいシステムや特殊契約、例えば実際にかかった人月で契約金額が決まるような契約でない限りはやるべきではない。契約段階で開発スコープを決めていないことには、最悪の場合、無制限な開発範囲の拡大を強制されてしまう。開発発注者側における発想の転換が必要ということだ。わたしがいままでやってきた開発は、幸い受託開発ではなく、SaaS開発が中心だった。それゆえ可能だったということを書いておく。