「プログラミング経験のない人がソフトウェアの設計をすること」の是非について、どう考えますか?

もしかしたら、このブログの読者であれば、プログラミングが出来ないのにソフトウェア設計をするなんてありえない!という意見の方が多いかもしれません。私もそういう意見ではあったのですが、色々な人と話をするにつけ、どこか違和感を感じていました。

その違和感の正体を探るべく、ソフトウェア設計とプログラミングについて考えてみました。そこでわかったことは「ソフトウェア設計」について、人それぞれに捉え方が違うために、話が通じないことがあることから産まれた違和感だったということです。

この記事では、私の考える「ソフトウェア設計とは何か」について書きました。

GARAGE VAILLANCOURTGARAGE VAILLANCOURT / ARBRE ÉVOLUTION

ソフトウェア開発はすべてが「設計」である

モノづくりにおいて、大きく工程を2つに分けるとしたら「設計」と「製造」に分けることが出来ます。何をどう作るかを決めることを「設計」と呼び、それを実際のモノにすることを「製造」と呼んでいると思います。

たとえば、家を建てようという場合は、建築士が「設計」を行い、大工が「製造(施工)」を行う、という役割分担だと考えられます。また、iPhoneの裏にはこう印字されています。"Designed by Apple in California assembled in China"。これは「設計」をカリフォルニアのアップルが行って、「製造(組み立て)」は中国で行われたということです。

このように、モノづくりでは「設計」と「製造」を分けて考えることが出来ます。

ソフトウェアの場合はどうでしょうか。ソフトウェア開発であっても「設計」と「製造」を分けて考えることが出来ます。では、ソフトウェア開発において「設計」とは何を指していて、「製造」とは何でしょうか。

ソフトウェア開発の業界にいる多くの人が、ソフトウェア開発における「製造」とは、プログラミングのことだと考えています。そのため、「製造」であるプログラミングだけをアウトソースできると信じています。

・・・果たして、本当にそうなのでしょうか?ここに大きな誤解があると感じています。

ソフトウェア開発において、人が最終的につくるアウトプットは、ソースコード(プログラム)です。しかし、ソフトウェア開発としては、それで終わりではありません。ソースコードをコンピュータが解釈して実行することで、動くソフトウェアとなります。コンピュータが解釈して実行するところまでを含めて、モノづくりです。ソフトウェアの特徴は、動かして初めてユーザにとって価値があるモノになるということです。

そのソースコードを作るためには、処理がどのように動くか、使われる変数名をどうするか、クラス名やメソッド名、メソッドの単位をどうするかを考えなければいけません。その行為は、まさしく、どう作るかを決めることであり「設計」と呼ぶべきことです。

さて、変数名やクラス名、メソッドの単位やアルゴリズムを「設計」した結果がソースコードだとするならば、「プログラミング」は「設計」であると言えます。ではソフトウェア開発の「製造」とは何かと言えば、コンピュータがソースコードを解釈して実行する、という部分にあたります。

つまり、ソフトウェア開発では、人が行う部分については全てが「設計」であり、コンピュータが担う部分こそが「製造」にあたるのです。

プログラマの仕事は「設計」であり、ソフトウェア開発の「製造」に人は要らないのです。

この考えは突飛なものではなく、1992年に書かれた論文「ソフトウェア設計とは何か?」に掲載された考えかたと同じものです。なんともう20年以上もの前の論文ですが、「ビルド=製造」だという考えは、プログラマであれば非常にしっくりとくると思います。

もし、変数名のひとつひとつ、アルゴリズムや処理の分割もすべてソースコードで表現する前に、なんらかの形で設計書として作ることが出来るならば、ソースコードにする部分だけをコーディングと呼んで、アウトソーシングすることも可能でしょう。

しかし、どう考えてもそれは非効率です。そこまで精緻な設計書を作れるとしたら、ソースコードを作る手間と変わらないはずです。むしろ、実際に動かすことが出来ない分、うまく作れないでしょう。

はるか昔、コンピュータリソースが非常に希少だった頃は、机上での設計とコーディングを分けることで効率を出せたのかもしれませんが、今や一人一台のコンピュータを占有できる状態の中で、設計とコーディングを分ける必要はありません。

そんな時代に、ソフトウェアの処理の中身をどう表現するかを考える「設計」という行為と、それをソースコードに「実装」する行為は、切り離して考えることはナンセンスです。

コンピュータがソフトウェアを「製造」するための設計図である「ソースコード」を「設計」する、という行為こそが「プログラミング」ではないでしょうか。

なので、プログラミングは、Excelで作られたような設計書をもとに、ただソースコードに変換していくような作業ではなく、マニュアル化のできない「設計」という高度な知識労働なのです。

そのためソフトウェア開発で、製造業の工場や家の建築をメタファにして考えることは間違っていると、私は考えます。そうであれば、アウトソーシングの考えかた、関係性も変えないといけないと思いませんか。

「設計」するのは「仕様」か「ソースコード」か

ソフトウェア設計において「設計(決める行為)」と「実装(表現する行為)」を切り離して考えないのであれば、「プログラミング経験のない人がソフトウェアの設計をすること」はありえません。プログラミングすることが設計だからです。

しかし、もう一つ曖昧にしている問題があります。ソフトウェアの「設計」という言葉には、「ソフトウェアのソースコードを設計する」という一面の他に、「ソフトウェアの振る舞いを設計する」という意味も含まれています。

「振る舞いを設計する」というのは、つまり仕様を決めることです。ユーザから見た画面や動作、動線、使う際にどう動けば良いか、が仕様であり、それを決めることも「設計」です。

(蛇足になりますが、「設計」という言葉が曖昧さを含んでおり、「○○の設計」と言わなければ、曖昧なまま相互理解が得られないという場面が多く見受けられますね。)

ソフトウェアの中身の"How"を設計するのが「ソースコードを設計する(=プログラミング)」ということであれば、ソフトウェアの振る舞いの"What"を設計するのが「仕様を設計する」ということになります。前者を内部設計、後者を外部設計と呼ぶこともあります。

現代において「ソースコードを設計する」ことに対してプログラミングのスキルが必要なのは否めません。しかし、「仕様を設計する」ことに対してはどうでしょうか。それもプログラミングと言ってしまうことには違和感を覚えます。

ソフトウェアの「仕様」の決定責任を持つのは誰でしょう。受託開発の場合は、お客さまの仕様責任者になるでしょうし、自社製品の場合であっても、仕様に関する責任者はいるでしょう。一つの製品しかもたない小さなスタートアップの場合はCEOが務めるかもしれないし、スクラムの言葉で言うとプロダクトオーナーの役割です。

たった一人でソフトウェアをつくるとしたら、自分自身が仕様責任者になりますが、それでも「仕様を決定する」自分と、「仕様を実装する」自分で、瞬間によって帽子を被り直しているはずです。

「仕様を設計する」役割を持つのが、プロダクトオーナーだとしたら、プロダクトオーナーはプログラミングが出来なければいけないのでしょうか?決してそんなことは無いように思えます。

「仕様を設計する」ことに対して、プログラミングのスキルが必要なのかどうか、そこが問題になります。

「設計」とは行為であって、「役割」にはならない

「仕様を設計する」ことに、ソフトウェアに関する知識やプログラミングのことを全く知らないで出来るものでしょうか。さすがにそれは難しいでしょう。どういう仕様が現実的か、出来ることと出来ないことの判断などは、プログラミング経験がないと出来ません。トレードオフの判断ができないのです。

だからといって、受託開発で言えばお客さまに、プログラミング経験がなくてはいけないかというと、それを求めるのは違います。そこで登場してきたのが、システムエンジニアという職業なのかもしれません。

ITやソフトウェアに関する知識を持ち、お客さま側の業務や解決したい問題について理解して、お客さまに代わって「仕様を設計する」役割としてのシステムエンジニアです。そして、システムエンジニアをするならば、プログラミングの経験が必要だという理屈が産まれます。

その理屈の結果としてあるのが、システムインテグレーターで働くシステムエンジニアで、入社数年はプログラムを経験した後、その後は「仕様を設計する」ことだけに専念し、プログラミングはアウトソース先に作らせる、しかし、仕様がヒドくうまくいかない、、、というよくある話ですね。

私は、ここに2つの大きな間違いがあったのではないかと考えています。

ひとつは、プログラミング経験があれば良いという考えです。現実的で良い「仕様を設計する」ことにプログラミングのスキルが必要なのは間違いありません。そこで本当に必要なのは、プロフェッショナルとして現役でプログラミングができるスキルです。入社してからの1〜2年程度の経験ではなんの足しにもなりません。

もうひとつは、「仕様を設計する」ことに専念する役割だという点です。その役割とは、よく言えば橋渡しをする、しかし、それはつまり伝言ゲームが産まれてしまうことを意味します。作りたいものがある人と、作れる人の間の溝は、この役割のせいで産まれます。

では、どうすれば良いか。「仕様を設計する」という行為には、プログラミングのスキルが必要だとして、必ずしも誰かが一人でしなければいけない訳ではありません。

お客さま、もしくは、解決したい問題を抱えている人、つまり仕様の責任者と、そのソフトウェアの開発を行うプログラマが、直接に話し合えば良いのです。その行為こそが「仕様の設計」なのではないか、と思います。

「仕様を設計する」ために必要だったのは、ソフトウェアで解決しようとしている問題のプロフェッショナルと、ソフトウェアを作るプログラミングのプロフェッショナルのそれぞれの協調作業だったのではないでしょうか。

「プログラミング経験のない人がソフトウェアの設計をすること」に本当の問題点があるとすると、非現実的な「仕様」が出来上がってしまって、プログラミングの段階では、いかんともしがたい状態になってしまって、それをそもそもの「仕様」の段階に戻って考え直すチャンスがない、ということではないでしょうか。

だとしたら、問題点は2点。「非現実的な仕様が出来ること」と「仕様の段階に戻って考え直せないこと」です。「仕様を設計する」ことにプログラミング経験がないことではありません。

それを解決するためにも、作りたいモノがある人と、モノを作ることができる人が協調して「仕様を設計する」ことが大事です。一方が、一方的に依頼して作らせるという関係ではうまくいかないでしょう。お互いのリスペクトが必要です。

自社製品のプロダクトオーナーや、受託で言うお客さまのような作りたいモノがある人が、プログラミングできるプログラマと話し合い、意見を受け入れられるようになっていれば、現実的で良い「仕様」が出来上がり、プログラマも納得感をもって開発が行えます。それができれば、作りたいモノがある人にプログラミングのスキルは不要なはずです。

設計にはプログラミング経験が必要か否か

最後に、最初の問いに戻りましょう。「プログラミング経験のない人がソフトウェアの設計をすること」の是非について。

ソフトウェア設計には「仕様の設計」と「ソースコードの設計」があります。

「仕様の設計」は、ソフトウェアを作りたいと思う人(プロダクトオーナー)には、必ずしもプログラミングのスキルは必須ではないですが、そのソフトウェアのプログラミングを行うプログラマが一緒に入って設計しなければ、良い設計は出来ないでしょう。

「ソースコードの設計」は、間違いなくプログラミングのスキルは必要になります。そもそも現代のプログラミングにおいて、ソースコードの設計とコーディングは不可分であり、それがもし分かれているとしたら、相当に非効率なことが起きているはずです。

これから先は「仕様を設計する」ことだけをする人の仕事はなくなるでしょう。
そして「ソースコードを設計する」ことだけしか出来ない人も生き残れません。