Design As Implementation

自分でもしつこいと思うが、アーキテクチャについて。実際に先日経験したことから書き留める。

同僚の開発プロジェクトに助言をしていて、システムのおおまかな構造の把握・設計をレビューした。そのプロジェクトでは、やっかいな既存モジュールを活用することになっており、それらがリスク要因であることは明らかだった。これらのモジュールは、利用側(つまり同僚が開発する方)の責任で「うまく」使ってやらなければならないが、仕様不在なのにモジュール間依存関係ありと、やっかいな代物だった。

この状況に対する僕の提案は、たいしたこともでもないが、要はそれらのやっかいなモジュールに対するアクセスを集約するクラスを用意することだった。そうすれば、何か望ましくない事態に陥ったとき、状況把握や原因究明などに無駄な時間を費やさなくて済む。

 

なんてことはない、提案の実体は「クラスを一つ用意せよ」でしかない。が、僕にはこれがアーキテクチャの本質のように思えてならなくなった。このクラスは、明らかにシステムに対する機能的な要求(外部仕様)からできたものではない。また、なにかの実装を行う過程や結果として必要になったクラスでもない。つまり、設計や実装から生じたものではない。

さらに重要なことは、このクラスの役割(アクセスをひとつにまとめることで、将来的なリスクに備える)は、このクラスの具体的な実装を待たずして「完成」していることだ。比較して、設計というものは、実装が完了するまではただの絵空事でしかない。設計実装の目的はなにかの機能の実現にあるのだから、設計が終わった時点で「機能が完成している」ということはあり得ない。しかし、いま述べているアーキテクチャ的なクラスについては、その存在と周囲の構造を採用すると決めた時点で、その目的が達成される。これは設計と大きく異なる。

 

この構造はもちろん僕が発明したものではなく、ファサードリファクタリングにおける “Introduce Gateway” と形は同じ。私が違うといっているのは、これらが「なにかとのアクセスをまとめる機能」のための構造なのに対し、「高リスクモジュールとの結合度を下げる」という構造的な決定の結果だということである。(ファサードのページには「サブシステム間の独立性を高める事を目的とする」とあるので、ファサードアーキテクチャ的に使えることは否定しない。)

最後に、これまでの議論を踏まえて、本稿で示した視点でのアーキテクチャに必要なものを考える。それは(コードではなく)構造によって実現可能な項目と、それに対応する構造例だ。実現可能な項目としては、

とか。ちょっと抽象的であやしい上にほかにもあるかもしれないが、今回取り上げた事例は後者だし、たとえば「Client-Server モデル」などは前者と言えるのではないか。特に後者についてまとめた書籍はあるのかな…。

 

と、蛇足になるが、実はもう一点だけ気になる視点がある。

それは、アーキテクチャが、システム開発を分割する前に適用しなければならない構造の集合である可能性である。可能性といったが、通常一般はこれだろう。「基本設計を始める前に決めておかなければいけないことのうち、構造に関するもの」という定義。

ある程度の規模のソフトウェアは複数人で開発されるから、並行して開発可能な単位にばらされなければならない。これには一定程度の構造が前提になっているが、その中には、一旦個別開発が進行したら後戻りできないものが存在する。たとえば、基本フレームワークだったり、セキュリティ、DBMSとの連携方式など。それらがアーキテクチャと呼ばれていることもあるようだし、位置づけに悩む。基盤的要素であることは間違いないが、構造に類するものなのやら…

 

(つづく)