2011年11月30日水曜日

OOPのオブジェクトを一貫することによるウェブサイトシステムの統合

現在のウェブサイト(サーバ)の多くは,MVC + DBの構成をとっている.MVCは,モデル, ビュー,コントローラ,DBはデータベースの略である.クライアントから要求Requestが送られると,サーバは,コントローラ部で解釈し,必要があればモデル部(+DB)での処理を経て,結果の情報をビュー部で描画プログラムに仕立て上げ,コントローラ部はそれを応答Responseとしてクライアントに送る.クライアントでは,ブラウザが送られてきた描画プログラムを解釈して画面を表示する.ユーザは画面を見て次の必要な要求をブラウザ経由でサーバに送る.ウェブはこのサイクルの繰り返しである.

ウェブの成功は,ひとえにこのサイクルにおけるHTMLとHTTPの簡素さに負っている.それぞれ,ユーザインタフェースとクライアント・サーバ間交信の本質を捕らえている.しかし,システム全体をみるならば,独自に発達してきた既存技術によって成り立つ部分の寄せ集めで構成され,とても統合されたシステムとは言い難い.使用される言語も各部分でばらばらであり,まるで複雑な寄せ木細工のようである.そのためシステム全体の見通しが悪く,その構築,保守管理,まして進化は,きわめて困難なものになっている.

では,たとえばGoogleのDartのように統一言語を設ければこの困難さは克服されるのかというと,そうではなく,それをどう使用するのか,肝心な問題が残される.また,処理対象のデータ表記をXMLで統一する試みも大分以前からなされているが,プログラム言語と同じく,それをどう使用するか,という同じ問題が残される.統合システムというのは一貫性を持つひとつの人工世界であり,それを作るためには,基礎づけるパラダイム(世界観)とその一貫性が必要である.まず,パラダイムの自然な選択としてOOPがある.

HTMLもHTTPも初期にはオブジェクト指向性は見られなかったが,1994年頃からJAVAなどのOOP言語が使われはじめ,また,DBとしてもっともよく使われるRDB(Relational Database)もOOPとの整合性,いわゆるO/R mappingが考えられるようになった.世紀が変わる頃には,HTMLでDOM(Document Object Model),HTTPでREST(Representational State Transfer)が導入され,OOP(HTTP1.1ではオブジェクトではなくリソースresourceと呼ぶ)が強く意識された.

しかし,これらはあいかわらず各部分ごとのOOP導入であるため,オブジェクト(ないしリソース)という語が共通に使われているにも拘わらず,じつはそれぞれの指示対象が異なっている.モデル部のオブジェクトはサイトの対象世界のオブジェクト(実世界の「何か」)の表現であるが,HTTPのオブジェクト(リソース)はGET, PUTなど作用actionが対象とする情報断片,ビュー部のDOMオブジェクトは文書の断片,という具合である.これらの寄せ集めでシステムを作る限り,とても統合システムとは言えない.すくなくとも系統だった(アドホックでない)相互対応の仕組みが必要である.全般を見渡す立場に立つフルスタックのRailsでさえ,ActiveRecordやRESTfulの導入などでこの認識は進んできたとはいえ,残念ながらいまもって不完全である.

オブジェクトを統一化するとは,じつは単純である.対象実世界の「何か」を,実世界をモデル化するモデル部のオブジェクトによって表現する.これを実世界オブジェクトと呼ぶことにする.DBは,実世界オブジェクトに関する事実データを記録する.クライアント・サーバ間のプロトコルは,実世界オブジェクトについての情報サービス要求形式とその応答形式を定める.コントローラ部は,クライアントからの要求を解釈し,モデル部(+DB)での処理を介して,処理結果をビュー部に送り,ビュー部はその描画としてDOMオブジェクトを作り,応答画面の一部とする.コントローラ部は,これをサーバの応答としてクライアントに送る.このように,ウェブシステムを,実世界オブジェクト(という情報断片)を処理し表示するシステムとみなすのである.

この統一化を行うことの端的なメリットを示す具体例をあげる.ユーザの入力エラーの表示である.入力値の検証は実世界に依存するから,モデル部の仕事であり,そこでエラーが検出されたとき,そのエラーの表示はビューでのその入力欄に近接しているのが良い.上述のようにオブジェクトが統一されていれば,入力画面でのDOMオブジェクトのID情報はプロトコルによる交信とコントローラ部を通じてモデル部に渡され,このIDにつながるエラー情報としてモデル部からコントローラ部とビュー部に渡すことが出来る.このようにするだけでエラー処理を系統立てておこなえるため,アドホックに作る場合の煩雑さを大幅に削減出来る.もちろん,統一化の御利益はこれだけではなく,システム全体の透明化と簡素化に寄与する.

この処理は,たとえば,商店のメタファーを使えば容易にわかる.クライアント(客)が商品を探すか,買うか,なにかしらのサービス要求をもって店(サーバ)に訪れる.客の応対担当の店員(コントローラ部)は客の要望(Request)を聞き,それをかなえるべく店の奥の商品処理担当の店員(モデル部+DB)に指示を出す.この店員はその結果を応対係に告げる.応対係は客にわたす商品を見栄え良くするための包装をするなどしかるべき処置をほどこす係の店員に指示し,その結果(Response)を客に渡す.ここで,客がもともと考えていた商品(ないしサービス)は,この商店というシステムでの一連の処理過程で,係が変わっても対象(つまりオブジェクト)として一貫している.工場をメタファーに使っても同様のストーリーになるだろう.つまり,分業された部分を通じての処理対象の一貫性は,システムが統合化されていると言えるためのもっとも基本的な要件なのだ.

Running Ruby on Rails(R3)は,Rails(とその土台とする既成のプログラミング領域)の補強によってこの統合化を行う.

しかも,R3の対象とするオブジェクトは,ここで述べたように単純ではなく,互いに関係し合いながら変化するのだから,通常のウェブシステムよりもはるかに複雑なシステムになることは避けられず,そのためにもこの概念整理による統合化とそれによる透明化がまず必要である.

2011年11月29日火曜日

すべてのものは互いに関係し合って変化する

情報システムは,情報サービスを提供するシステムである.情報サービスとは,対象世界について何かを知りたい,あるいは対象世界の情報に対するなんらかの操作をしたいという要求に応えることであり,応えるための処理が情報処理である.

情報処理の手順を記述するための言語がプログラミング言語であるが,言語である以上,その記述対象世界が想定されている.初期のプログラミング言語である機械語とアセンブラ語はコンピュータのハードウエアをその対象世界としていた.それを高度化した(当時の言葉でいえば)高水準言語はそれをより一般化して,「計算(数値計算と記号計算)」の世界を対象とした.それをさらに高度化し,実世界を記述の対象とする言語が本当は求められるのだが,残念ながら,1980年ころまでの素朴な人工知能ではこのことが強く意識されていたものの,いつの間にか,その志は薄れてしまったようだ.プログラミング言語界では,実世界記述志向時代の名残として「関数型」「論理型」「オブジェクト指向」の区分けがあるが,単なる計算の仕組み,つまり計算のパラダイムとしてのみ見られるようになった(たとえば,Bruce A. Tate著 "Seven Languages in Seven Weeks" 2010).求めるべきは,じつは実世界に対する世界観,すなわち本来の意味でのパラダイムのあり方である.

そのような状況の中で,2004年に出現したRuby on Railsは,この停滞を越える方向に強く踏み出した.現代情報システムの大半は事実上ウェブサイトシステムになりつつあるが,そのフルスタックのフレームワークであるRailsは,サイトの対象世界を一貫してOOP(オブジェクト指向パラダイム)で見る姿勢を貫き通すシステムである.Railsは,通常,強力かつ柔軟なフレームワークとして評価され,それによって多くの実用システムが作られ,もちろんその意味ですでに十分価値あるものになっているが,このようなプログラミングの高度化という方向性から見ても,高く評価されるべきだろう.

では,Railsはその役割をすでに果たし終えたのだろうか.つまり,さらなる高度化はもう必要ないのだろうか.私にはそうは思えない.単なる机上の議論からではなく,実際にシステムを構築する実践を通じて得た私の考えである.

世界は何かの集まりである.この「何か」を,オブジェクトobjectと呼んだり,実体entityと呼んだり,用語は様々であるが,「何か」は「何か」であって,要は,人は認識によって世界を分節する.分節しなければ世界は一色(つまり「空」)で認識にならないからである.この分節された「何か」によって世界が構成される,と我々は認識する.この「何か」をもとにして世界を見るというのがいわゆるOOPの出発点である.しかし,現在の情報処理技術におけるOOPが本質的に見落としている側面がある.

武田泰淳は次のようにいっている.
すべてのものは変化する
変化するものは
互いに関係しあって変化する 
個人では生病老死,学校では学生の進級,会社では人事異動と組織変更,それが実世界である.そのような実世界を正確に,そして容易に記述できる仕組みが実用の情報処理システムにとって必需なのだ.にも拘わらず,現在のOOPでは,Railsを含め,「互いに関係し合って変化する」ものとしてのオブジェクトを十分に明晰にしていない.

私の開発したシステムでは,モデル部とコントローラ部それぞれに共通する機能を提供することによって,このような実世界を統一的に記述する仕組みを作っている.わずか数千行のRubyプログラムをRailsに追加するだけである.この体系を名付けてRunning Ruby on Railsと呼ぶことにする.Ruby on Railsをrun(実行)するということでは,もちろんない.

このブログでは,Running Ruby on Rails の考え方とその具体的技法について逐次紹介していく.