2010-12-29

"Beautiful Architecture" Diomidis Spinellis & Georgios Gousios 編

本書を購入したのは一年前であろうか。買ったはいいが積み上げたままの専門書が数十冊にのぼるのには頭が痛い。とりあえず、こいつは本年中に片づけておこう。
「ビューティフルアーキテクチャ」は、オライリー君の「ビューティフルコード」に続くシリーズ第2弾。アーキテクチャといえば個人的にはハードウェアの印象を与えるが、ここではソフトウェアアーキテクチャを題材にしている。

近年、マシン性能の向上やネットインフラが高度に整備される中で、ソフトウェアが巨大化し社会の仮想化を加速させる。そして、社会に利便性をもたらす影で、OS、Webアプリ、プログラミング言語など、あらゆるソフトウェアの脆弱性が問題視される。Web開発環境では、この言語を用いればセキュアなコードが書けるといった優位性を強調しあう。だが、どんな開発手段を用いたところで、安全性の高いソフトウェアを開発するのは難しい。そもそもハードウェアを動作させるためのプリミティブな言語が存在し、言語の脆弱性を言語でカバーするといったことを繰り返しても、いずれ自己矛盾に陥るであろう。となれば、開発プロセスへの取り組み方などの慣習が重要となる。それは開発者の哲学的思想に拠るところが大きく、その思想と深く結び付くのがソフトウェアアーキテクチャであろう。そして、プログラム思想からマネジメント思想に至る開発プロセス全般に関わることになる。
古くからソフトウェア工学では、信頼性、移植性、再利用性といった問題が議論されてきた。プログラムが巨大化すれば、多くの技術者が携わることになり、開発思想の一貫性を保つことも難しい。そこで、コードを超えたレベルでの抽象化や構造化の手法が求められる。システムが複雑化するからこそ、設計思想はできるだけシンプルでありたいものだ。

一つのソフトウェアとして完成させるためには、設計思想から逸脱したコードが一つでも紛れ込むと不具合の原因になりやすい。せっかく良い思想に統合されたシステムであっても、安易な機能追加や修正によって本来の思想を破壊してしまうことがある。応急措置やその場しのぎの対策は、後に技術的負債となって返ってくるものだ。しばしば目先の開発日程を優先するあまりに、ソフトウェア資産の流用を政治的に強要されることがある。それは「ブラックボックス」と名付けられ、あたりに異臭がたちこめる。上層部は、その資産が対象システムに調和するかなど構っちゃいない。彼らは黒箱に潜む黒幕と仲良くしたいらしい。
悪い設計には、その上に更に悪い設計が覆いかぶさるようにできている。腐りはじめたモジュールは次々と伝播し、開発プロセスやスケジュールに影響を及ぼし、ついには人間関係にも波及する。おまけに、メンバーのモラル低下や意欲低下を招き、技術魂をも失わせるであろう。どこぞの政治システムのように。したがって、マネージャには、簡潔な思想を損なうような安易な思考の流れに抵抗する資質が求められる。
「良いシステムアーキテクチャは、概念の統合を体現しています。つまり、複雑さを減じるのに役立つと同時に、詳細な設計やシステム検証の手引きとしても使い得るような、設計規則一式を備えるのが、良いシステムアーキテクチャです。」
アーキテクチャとプロジェクトチームには相関関係があり、相乗効果によって好転させるであろう。アーキテクチャは、設計仕様や図面といったもので表現できる単純なものではない。レビューや会議、検証工程や修正プロセス、あるいは意思決定プロセスに関わり、いわば組織文化の設計に関わると言っていい。ちなみに、プロジェクトマネジメントで最も重要なことはメンバーの哲学的認識の共有だと思っている。それは技術者魂に則ったもので、その認識が一致していれば問題が発生した場合でも少々無理がきく。
オープンソースのような形態では、開発者たちに自由という崇高な哲学思想が根付いている。自由とは、相手の思考を尊重することを意味し、けしてわがままを許さないだろう。好転したプロジェクトの影では、あらゆる意思決定の権限を持つマネージャが、慈悲深い独裁者として振る舞っているものだ。
本書には、オブジェクト指向提唱者のバートランド・メイヤーをはじめ19人もの開発者によってソフトウェア哲学への思いが込められる。彼らは、仮想化やスケーラビリティ、データ構造の美、エンドユーザによる拡張性、言語の原理と構造などから眺めたアーキテクチャを議論し、最後の章では古典の再読を勧めている。思想というものは歴史的に育まれるものであり、その根本思想を古典に求めるのは大切であろう。
そして、アインシュタインの言葉「すべてをできるかぎり簡潔に、ただし簡潔すぎないようにしなさい。」をアレンジして、「美しいアーキテクチャとは、最大限に簡潔であり、そして簡潔すぎないようなものだ。」と語る。

1. スケーラブルのためのアーキテクチャ設計
不特定多数に仮想世界を提供するようなサービスでは、スケーラビリティの問題が重要となる。実際に、突然数百万人がアクセスして破綻したサイトやサーバを見かける。マシン性能やネット環境が充実すれば、オンラインアプリケーションに求められる機能も複雑化する。オンラインゲームでは、急激に人気を博して負荷が増大する場合もあれば、急激に需要が減って撤退する場合もあり、システムの増設や削減に対して柔軟に対応しなければならない。そこで、分散かつ並列システムは必然となる。オンラインゲームは、マルチコアチップと分散システムの検証には、うってつけの分野かもしれない。
しかし、ゲームプログラマたちに、並列プログラミングや分散システムといった高度な専門知識を要求するのは難しいという。そこで、メイン機能は単一スレッドを実行する単一マシンを想定しておき、ジョブを複数マシンや複数スレッドに配置する機構は別に管理する例を紹介している。つまり、プログラマから並列性や分散性を隠蔽する仕掛けで、ロックのプロトコルや同期やセマフォなどを、ゲームプログラムのコードに一切含めないというわけだ。だが、並列性を完全に隠蔽することはできなかったという。プラグラマたちに、並列アクセスを念頭に置いた設計が必要であるという意識を持たせる努力もしたという。
定義するオブジェクトは自己完結し、依存性を極力避ける構成にするのは望ましい設計原理ではあるのだけど。その範疇に収まらないケースでは、システムの特性を意識させるような指針のようなものを提示する必要があるだろう。

2. リソース指向アーキテクチャ
企業システムの情報集中型アーキテクチャは、スケーラビリティ、フレキシビリティ、アーキテクチャのマイグレーション戦略、情報駆動のアクセス制御など、多くの特徴においてWebと類似しているという。
にもかかわらず、Web上のデータ管理と、企業内の情報管理の仕組みが原理的に異なるケースが多いのはどういうわけか?それは技術選択よりも企業ポリシーに縛られるからであろうか。従来のレガシーなシステムがボトルネックになることもあろう。インフラ技術の進化した組織でさえ、管理者と消費者の間で領分の争奪戦が起こるのが人間社会というものである。情報管理部門が自らの存在感を無理やり強調するために、奇妙な規定をシステムに盛り込むことすらある。こうなると、技術的な問題は政治的な問題にすり替えられる。
そこで、Web技術が政治的問題を迂回するという。Webの成功はまさしく情報の共有にあるから。リソース指向の形式では、リソースに対して論理リクエストを発行するというプロセスが特徴にある。リクエストはエンジンによって解釈され、対象リソースの物理表現、例えばhtmlやxmlの形式、あるいはJSONなどに変換される。そして、データ駆動型によって、ビジネスインテリジェンスや知識マネジメントなど新たな統合戦略が導入できるという。

3. Facebook プラットフォーム
「私にフローチャートだけを見せて、テーブルは見せないとしたら、私はずっと煙に巻かれたままになるだろう。逆に、テーブルが見せてもらえるなら、フローチャートはたいてい必要なくなる。それだけで、みんな明白にわかってしまうからだ。」
...フレデリック・ブルックス著「人月の神話」より。
高度な情報化社会では、ユーザに対するサービスの価値よりも、データそのものの価値が高まった。となれば、コンテンツの見せ方や可視化規則といったポリシーが重要となろう。高速にデータを取り出すための仕掛けでは、データ構造は重要な役割を占めるだろう。
Facebookは、データ周辺に構築されたアーキテクチャの良い例として紹介される。そして、プラットフォームとして構築される過程で、データ構造が成長する様子を物語る。
SNSの世界では、周辺アプリを一般ユーザによって整備されてきた例は多い。サービス開始当初は思いっきり使い勝手が悪かったりするが...
Facebookでは、外部システムと連携しながら統合的なシステムへと進化し、ユーザのソーシャルデータがアーキテクチャの中核になったという。プラットフォームは、Webサービス(Facebook API)から、クエリ言語(FQL)やデータ駆動型マークアップ言語(FBML)へと進化し、アプリケーション開発者がこれらを使って自分のシステムとFacebookを統合できるようになったという。
ただ、Facebookは個人情報の扱いでいろいろと物議をかもす。「Like」ボタンは大手新聞社などが取り入れたらしい。ユーザの趣味や好みを把握しながらターゲットマーケティングを強化するということは、個人情報の公開とも解釈できそうだし...

4. Xenと仮想化の美
Xenは、一つの物理マシン上で複数のOSを実行させるための仮想化プラットフォームである。これは、ケンブリッジ大学の研究から始まったが、GNU GPLライセンスでオープンソース化によって発展した例である。
オープン化によって純粋な議論の中で育まれた技術は、純粋な技術者魂を呼び覚ますような空気がある。ある種ボランティア的で、組織の垣根を越えた共通精神のようなものが育まれる。客観的な自由を求めるならば、組織の主観的呪縛から解放されたいと願うだろう。
また、仮想化の概念が、ソフトウェア技術に大幅な進化をもたらしたことは間違いない。CPUやデバイスなどの仮想化が限られたハードウェア資源の共有をもたらし、メモリの仮想化がソフトウェアの可能性を拡げてきた。MMUは、ページテーブルがメモリの拡張性やメモリ保護機能を与え、物理アドレスから仮想アドレスを扱えるようにした。
Xenは、IntelとAMDのCPU拡張をサポートする最初のハイパーバイザーになったという。
他にもBochsやQEMUやVMWareなどの仮想化があるが、マシン資源の限られた貧乏人にはありがたい機構だ。

5. Guardian: フォルトトレラントなOS環境
1970年代のお話。Guardianは、Tandem社のフォルトトレラント(無停止型)なコンピュータ「NonStopシリーズ」のためのOSで、単一障害点が生じないように設計されているという。つまり、システムの構成要素のどの一つが故障しても、全体としては故障しないように考慮されているというわけだ。そのターゲットは銀行システムやATMなど、自己診断と自己修復が必要な業界である。
最初の実装は、バックアップのために各コンポーネントが少なくとも二つずつ用意されたという。CPUにしても二つ以上実装される。ファイルの対構造や、メモリ上で動作するプロセスが対になって動作させることが、フォルトトレラントの基本的思想である。となれば、対になって動作させるための調停機構が必要となろう。その基本概念が、診断、修復、同期ということになろうか。
いずれにせよ、修復能力は確率論に持ち込まれるわけだが、自然界の実践的な解に二重構造があるのかもしれない。などと思うのも、遺伝子コピーの不完全性に対するバックアップ機能として、DNAの二重螺旋構造があるからである。ディスク上でファイルを管理するFATも、テーブルを二重に持って読み出しエラーを抑制する。RAIDなどのバックアップシステムにしても、その基本思想は二重化である。Tandemコンピュータは、その先駆けだったのかもしれない。
しかし、その革命的なシステムであるにもかかわらず、業界への影響は少なかったそうな。ディスクのミラーリング、ネットワークファイルシステム、クライアントサーバモデル、ホットプラグ可能なハードウェアなど、その根源をTandemに見出すことはできないという。歴史に登場するのが早すぎたということであろうか。

6. Jikes RVM: メタサーキュラーな仮想マシン
Jikes RVMは、Javaアプリケーションを実行するための仮想マシンで、Javaで書かれているという。最適化コンパイラ、スレッド機能、例外処理、ガベージコレクションなどもJavaで書かれているらしい。コンパイラを自己ホスティングするのは当たり前だが、実行環境の多くは実行する言語で書かれていない。例えば、CやC++で書かれた実行環境が、Javaアプリケーションを実行したりする。Java言語がいくらメモリ安全性を主張したところで、実行環境のシステムに問題があれば意味がない。したがって、実行環境においても自己ホスティングするのは重要な意味があるという。ちなみに、自己ホスティングな実行環境のことを「メタサーキュラー」という。
マネージド実行環境は、特定のOSやCPUアーキテクチャに依存しない抽象化された環境を提供する。そして、マネージド環境のための言語は、アプリケーション設計の間違いを犯しにくくする。ユーザは、開発モデルを単純化し、ただ言語の提供する機能に従えばいいのだから。ただ、開発ツール自体がアプリケーションであるから、最良のアプリケーションを作成するということは自己言及的でもある。今日では、スクリプト言語や数値演算言語など、状況に応じて最適な実行環境を選択できるようになった。多くのマネージド環境の恩恵を受け、ネイティブコードに触れることもなくなった。
そういえば、10年以上前に何かとネイティブコードと連呼するオヤジがいた。当時、雑誌ではコンパイラの性能比較やらでネイティブコードで盛り上がっていたような気がする。対象システムは、製造ラインで制御するマイコン群の動作状況をモニタするだけで、大したリアルタイム性もない。逆にネイティブコードの方が恐ろしいように感じたが、どうやって管理するんだろう?と不思議に思ったものだ。ちなみに、彼を「ネイティブおじさん」と呼んでいた。

7. GNU Emacs: 漸進的機能追加方式が持つ力
Emacsが、Lispによって拡張性が高いのは広く知られる。ただ、その使い勝手では意見が分かれるだろう。単なるエディタの域を超えて、多様なプラットフォームもどきにもなっている。telnetやsshの端末やメーラなど。なによりも、拡張性はユーザ任せという特徴がある。そのアーキテクチャは、対話的アプリケーションで普及するMVC(モデル, ビュー, コントローラ)パターンに従うという。モデルの中心はバッファ型で、ちょいと操作してみれば、画面の表示切替がバッファと連動して重要な役割を果たしていることが分かる。バッファがオブジェクトという意味合いを持っていて、表示される場面に応じて使えるコマンドも決まり、Lispで操作できる変数も決まる。バッファ毎にundoなどのロギング機能を持ち、マーカで操作位置を保持する。
再表示エンジンであるビューは、二つの特徴があるという。それは、表示の自動更新と、ユーザが入力待ちの時だけ表示を更新すること。表示を更新するべき時に、累積変更点を効率的な集合体として渡す。こうした機構が、Lispから画面を管理する負担を除き、連続コマンドによるマクロ機能やバッチ処理的な拡張性をより高めているという。また、コントローラは、ほぼ全面的にEmacs Lispのコードである。

8. オブジェクト指向 vs. 関数型
バートランド・メイヤーは、オブジェクト指向と関数型の比較から、その優位性を論じている。そして、サンプル数が少ないとしながらもオブジェクト指向に軍配を上げている。まぁ、Eiffel開発者としては当然かも。しかし、オブジェクト指向言語の中にも関数型の特徴が多く含まれるので、対立関係にあるというわけでもなかろう。拡張性や再利用性の観点から抽象レベルではオブジェクト指向が優勢であろうが、場面によっては関数型言語の方が軽い。関数型言語はLispで代表されるように歴史は古いが、今ではScheme, Haskell, OCaml, F# などの新言語により復活を見る。
関数型言語の魅力は表記が簡潔なところにあるが、その特徴をオブジェクト指向言語に取り入れているものも多い。いずれにせよ、万能な言語は存在しないだろう。オブジェクト指向で特徴づけられる継承の概念も、実践するとなると難しい。どのレベルで継承するか、その抽象レベルは慎重に検討しないと逆に混乱を招く。だいたい設計した後に継承構造の弱点が目立ち、いつも修正したいという衝動が付きまとう。したがって、忘れることが精神的に健全であり、続けるコツである。そして、次回も同じ失敗を繰り返す羽目になる。アル中ハイマー病とは、永遠に学習能力が身につかない病であった。

1 コメント:

アル中ハイマー さんのコメント...

本書で紹介されるイタロ・カルヴィーノ著「なぜ古典を読むのか」の古典の定義は印象的だ。
「...古典とは、ふつう、人がそれについて、「いま、読み返しているのですが」とはいっても、「いま、読んでいるところです」とはあまりいわない本である。...」
絶版中はなんとも惜しい!

コメントを投稿