2018-01-16

Cプログラマのための、
C++オブジェクト指向簡単裏口入門(6)

変化に寄り添えるオブジェクト指向

大前提として、システム開発というものは一度の開発サイクルで終わることは希である、という点は確認しておきましょう。
バグのないシステムを構築したとしても、ユーザが使っているうちに問題点や改善点が見えてきます。そして機能の修正や追加が繰り返されて完成度が増していきます。これは悪いことではないし、成功しているシステムはそういうものです。

ソフトウエアはハードウェアに比べて変更しやすいというのは、これはもう抗えない宿命です。つまり、システム開発は潜在的に変化に追従していく義務があるのだと思うのです。

そこで、ソフトウエアの品質を計る要素の1つ、「保守性」が登場するわけです。

ここで言う保守とは、機能を維持する、という消極的なものだけではなく、システムの改築までを視野に入れたより広い範囲を指します。

保守性に問題があると

初版のプログラムは概ね設計通りにできたとしても、何度も改造を繰り返すうちにプログラムコードは時間つぶしには最適の迷路パズルゲームと化し、その難易度は高くなる一方で、最後には手が付けられなくなって開発サイクルはすぐに終焉を迎えてしまいます。

ありがちですが、どうしてそうなってしまうのでしょうか。

1つには予算の問題が挙げられます。
システムの改修にかかる費用が割高に思えるのは、新車の購入金額の割に修理の部品代が妙に高く感じられるのと似ています。車1台分の部品をバラバラに購入したら新車が何台買えることか・・・?
車の部品には定価があるので、工賃を少し負けてもらうくらいしかできません。
しかし、ソフトウエアの改修は基本は全てが人的工数ですから、どうしても無理をさせられてしまいがちです。
無理をした結果、改修の繰り返しは悪循環と化し、地獄へ落ちていくのですね。

しかし、実際にプログラムの改修というのは、100%自由に作ることができる新規開発に比べて工数がかかるのは仕方がない面もあります。

なので、これをいかに軽減できるか、そこが焦点になります。

オブジェクト指向でどのようにこの問題を解決するのか

理想はプログラム改修の工数が、その機能改修によって生み出される価値と一致するか、更にそれを下回るようにすることです。

しかし、オブジェクト指向は決して魔法ではありません。これを取り入れたからといって、一気に理想に近づける訳ではありません。しかし、そのポテンシャルは十分に備えていますから、習得の為の労は必ず報われるはずです。少なくとも、僕にはそう感じられるので、これまで楽しくオブジェクト指向プログラミングに取り組んで来ることができました。

蛇足ながら、「楽をするための労は惜しまない。」という僕のスタンスにぴったりの技術でもあります(BLOG記事『忘れられた合理性の追求』を参照のこと)。

こんなことを書くと、ここ以降は茨の道になるように誤解されるかも知れませんが、そんなことはないのでご安心ください。

オブジェクト指向の神髄を紐解いていきましょう。

肝となる写像という考え方

オブジェクト指向の聖書(偉い人が書いた書籍)には、よく現実をモデル化したものをそのままクラス(オブジェクト)にする、といったような言が書かれています。
我々プログラマはその持って回った言い方によく惑わされてしまいます。
技術者ではないマネージャがこの話を聞くと、オブジェクト指向がまるで魔法のツールのような誤解をして我々技術者を困らせることもあります(実話)。

現実にプログラムを対応させる、と言っても、コンピュータの中にはそれとは無関係なオブジェクトと呼べるものがたくさんあります。ファイルシステムやディレクトリ、ファイル、データベース、メモリやネットワーク等々。プログラムが意識する対象の多くはそんなものが中心だったりしますね。

現実をモデル化したもの、それはたとえば「人」。人というオブジェクトが、コンピュータ内部に特有のオブジェクトと同列に存在することに、違和感を覚えずにはいられませんね。

でも実は、そこは階層を分けて考えればいいだけなのです。簡単な話でした。
簡単だけど、この説明を直接書いてある書籍に出会ったことはありません。


ただし、この聖書に書かれている言葉にはとても大切なことが隠されています。
それは、オブジェクトが対象を良く表したものであることが求められるという点です。対象が現実社会の何かをモデル化したものであっても、あるいはコンピュータの内部のことであったとしても同じです。
オブジェクトはプログラムが扱う「もの」であって、対象そのものではありません。対象に対して、オブジェクトは写像であると考えます。

写像であれば、その元になる対象に変化があっても、写像も同じように変化させればよく、回りくどい修正は必要無いはずである、と考えるのですね。

従来型のプログラムの問題点

逆に、オブジェクト指向ではない従来のプログラムではどうだったかを思い出してみましょう。

まとまりのあるオブジェクトという構造は存在せず、対象を操作する関数だけがありました。ひょっとしたら関数の操作対象は1つだけではなく、同時にいくつかの対象を操作するものかも知れません。その方が都合が良かったのでしょうね。

そこで、1つの対象に変化があり、プログラムがその変化に対応しなければならなくなったとします。

まず、その対象の変化により、プログラムのどの部分に影響があるか、その全てを調べるのに大きな労力が必要です。あちこちにそれを操作する関数が分散しているからです。
そして、操作対象が複数になっている関数やプログラムの場合、無関係な対象に影響が出ないように慎重に行う必要があり、これまた膨大な時間がかかってしまうことになります。

オブジェクト指向という筋の通った考え方に沿ったプログラミングから見ると、従来型のプログラムには節操がないように見えてしまいます。


今回は具体的なプログラミングの例を示すことができませんでしたが、次回からは具体的なオブジェクトのプログラミングに入っていきたいと思います。

コラム:オブジェクト指向の習得

僕は、C言語の習得にはさほど時間を要しませんでした。本を読んで、割とすぐに使えるようになりました。
それは、関数というサブルーチンで機能分担していくという考え方がとてもシンプルで解りやすかったからだと思います。(ポインタについてはそれ以前にアセンブラも学んでいたので、さほど難しいとは感じませんでした)

しかし、C++は本を読んでもいきなり使いこなせるところまで行きませんでした。C++はCを含んでいるので、動くものにすること自体は可能でしたが、オブジェクト指向プログラミング、という観点ではそう易々と習得できるものではなかったのです。

それには理由があります。オブジェクト指向をパズルに喩えると、その解は1つではなく、実際にかなりの数があります。無機的に数えてしまえば従来の構造化プログラムであっても無数にある、としか言えません。そうではなくて、概ね妥当であると判断できる正解がいくつも存在するという意味なのです。
これは、主にオブジェクト指向におけるクラス設計について言えることです。

クラス設計をするというのは、外国語の会話を習得するのに似ています。文法を覚えたり、単語を暗記しただけでは外国人との会話はできません。会話の訓練が必要です。オブジェクト指向のクラス設計にもそのような訓練が必要だと考えています。

それを誤解し、何冊か本を読んでも使えるようにならず、諦めてしまう人も多いのかも知れないですね。

しかし、僕にはクラス設計の妥当性を考えることはとても楽しいと感じられます。このことで人と議論することは、ソフトウエア開発の醍醐味の1つだと言えます。
是非、読者の方にもその楽しさを感じられるところまでになって欲しいと願います。オブジェクト指向開発に完全なゴールはないかも知れませんが、その楽しさを感じられるようになることは、大きな目標としていいと思うのです。

0 件のコメント:

コメントを投稿