« 業務システム向けのデザインパターン | トップページ | 「データモデリングライブ@渋谷(9/29)」のお知らせ »

2012.09.04

デザインパターンそのものをプログラミングする

 前回記事で示したスクリーンショットはいずれも実際に動作するアプリのものなのだが、従来のように人手でプログラミングされたものではない。それらは「仕様書」としてのみ存在する。それをある種のインタプリタに渡すだけで、仕様にしたがって動作するアプリが動的に立ち上がる。コードの自動生成も伴わない。

 そのインタプリタは、前回記事で説明した「デザインパターン」毎に用意されている。つまりそれらは「プログラムのパターン」そのものをプログラミングしたものである。このようなプログラミングを「メタプログラミング」という。私はこれが、業務システムの開発・保守効率を劇的に向上させる鍵のひとつだと考えている。

■メタプログラミングの威力

 なぜなら、パターンそのものをプログラミングしておけば、そのパターンに類型化されるアプリをいちいちプログラミングせずに済むからだ。個々のアプリに求められている処理要件を洞察して、対応するインタプリタに渡すべきパラメータとして様式化する――これでアプリの仕様書作成と実装とが同時に完了する。従来の「まとめられた仕様書を見ながら手作業でコード化する」という後工程が要らない。

 手作業による仕様のコード化やそれに続くテストこそが、業務システム開発を労働集約型産業に引き留めていた元凶である。これまでもテスト(とくにユニットテスト)の省力化についてはさまざまに工夫されてきたが、それに先行する手作業のコーディング工程が存在する限り、効果は限定的である。そもそもコーディングを不要にすればユニットテストも要らなくなる。そのための有力な手段としてメタプログラミングはもっと注目されていい。

 ちなみに、前回記事の初めに紹介したアプリ「Aの一覧」の仕様書の実体は、次に示すようなXMLセグメントだ。これを専用の仕様書エディタで読み込めば、Excel方眼紙あたりをつかうよりもはるかに使いやすい形で閲覧・編集できる。そして、この仕様書を「明細一括表示(XF100)」のタイプのインタプリタに渡せば、インタプリタが仕様書どおりのアプリにメタモルフォーゼ(変態)して立ち上がる。この小さな文字列データはまさに「そのまま実行可能な仕様書」だ。

20120904b

 それにしても、この文字列データの圧倒的な小ささは何なのだろう。「アプリの仕様書」の実体としてはひどく情報量が少ない。

 それは、アプリの仕様書にビジネスルール(業務ロジック)が一切含まれていないためだ。「『フィールド値の色』をテーブル定義に組み込む」で説明したように、「妥当性検査」も「導出項目の設定手順」も「結合テーブルへの参照手順」も、テーブル側の拡張定義(リポジトリ)として格納できてしまう。そうなれば、インタプリタも仕様書エディタも、フィールド定義やビジネスルールを必要に応じてリポジトリから取り出しつつ動作すればよい。SQLも動的に生成されるので仕様書に含める必要がない。ゆえに個々のアプリ(仕様書)は「ありきたり(類型的)でうすっぺら」で済むのである。

 このようにアプリとビジネスルールとを分離することの意義は、想像以上に大きい。たとえば、あるテーブルのレコードをパネル上で更新するアプリの仕様書を作ったとする。その後にそのテーブルに対して妥当性検査等のビジネスルールを新規追加しても、既存の仕様書を書き換える必要はない。なぜならインタプリタは、リポジトリから定義情報を読み込み統合したうえで動的にアプリを立ち上げるためだ。

 しかも、分離されつつも両者の整合性が失われることはない。たとえばテーブル上の有効なカラム定義を間違ってドロップしようとすれば、仕様書エディタが「そのフィールドはホニャララのアプリによって利用されているので削除できません」と警告してくれる。アプリとビジネスルールとは分離されながらも、開発環境によって整合性が監視され続ける。

■「バッチレコード処理」の実際例

 さて、メタプログラミングは強力な技法だが、万能ではない。下手にやればかえって混乱を招くだけだ。ではその成否は何で決まるのか。言うまでもなくそれは「どんなパターンを揃えるか」にかかっている。選りすぐりのパターンを確立することこそが肝要で、確立されたパターンをメタプログラミングすること自体は、それほど難しいことではない(*1)。

 じっさい、前回記事の最後に紹介した「バッチレコード処理」のような複雑なデザインパターンもメタプログラミングできてしまう。そのことの意義とデザインパターンの有用性をよりよく理解してもらうために、実際的な例でこのパターンの動きを再度説明しよう。

 次図のように受注見出しと受注明細が親子関係、受注明細と出荷指示とが参照関係を成しているとする。受注見出しのタプルが3件、受注明細が5件存在しており、いずれも未出荷の状態である(つまり、明細5件に関連する出荷見出しレコードが存在しない)。このモデルにおける受注明細と出荷指示とがそれぞれ、このUIパターンにおける「一次テーブル」と「バッチテーブル」に相当する。

[受注見出し] {受注№},受注日,顧客№,...
+       J256  ...  T100 ①
|       J257  ...  T200 ②
|       J258  ...  T100 ③

|  <一次テーブル>
└─∈[受注明細] {受注№,行番},品番,数量,出荷№,...
┌─…       J256 01  S333  20 (null) ④
|         J256 02  S555  10 (null) ⑤
|         J257 01  S222  30 (null) ⑥
|         J257 02  S444  10 (null) ⑦
|         J258 01  S111  50 (null) ⑧

+ <バッチテーブル>
[出荷指示] {出荷№},出荷日,顧客№,...
     (レコードなし)

 このデータ状況で、受注明細5件について「出荷指示」することを考える。すなわち、受注明細タプルを調べ、新たな出荷指示タプルに関連付けさせるように指示する。この処理の過程で受注明細は「顧客№」毎に2つの「バッチ」に分けられ、それぞれ毎に出荷指示タプルが1件追加される。

 結果的に、データ状況は次図のように変化する。それまで「受注単位」のみでまとまりを成していた受注明細データが「出荷指示単位」でもまとめられたことになる。「出荷指示書発行」や「出荷完了報告」といった活動はこの新たなまとまり毎になされる。受注のまとまりで出荷したり売上計上したりしなければいけない義理はないからだ。

[受注見出し] {受注№},受注日,顧客№,...
+       J256  ...  T100 ①
|       J257  ...  T200 ②
|       J258  ...  T100 ③

|  <一次テーブル>
└─∈[受注明細] {受注№,行番},品番,数量,出荷№,...
┌─…       J256 01  H333  20 S123 ④ ←更新
|         J256 02  H555  10 S123 ⑤ ←更新
|         J257 01  H222  30 S124 ⑥ ←更新
|         J257 02  H444  10 S124 ⑦ ←更新
|         J258 01  H111  50 S123 ⑧ ←更新

+ <バッチテーブル>
[出荷指示] {出荷№},出荷日,顧客№,...
       S123  ...  T100 ⑨ ←追加
       S124  ...  T200 ⑩ ←追加

 レコードの対応関係を模式化すると次のようになる。「一次テーブル上の複数レコードを、新たな条件でバッチテーブル単位にまとめなおす」という表現で形式化できるデータ処理が起こっていることがわかるだろう。この形のデータ処理要件が、業務システムには繰り返し現れるのである。

20120904

 じっさい、拙作の販売管理システムのモデルライブラリでは、以下の5つのアプリに対してこのデザインパターンが適用されている。一見するとそれぞれユニークで複雑なアプリに思われるのだが、じつは互いに「相似形」である。こういった高度な処理さえ仕様書を書くだけで(SQLさえ一切書かずに)実装できてしまうのだから、このデザインパターンとメタプログラミングの威力がわかるだろう。

・支払依頼エントリー
・支払指示エントリー
・請求エントリー
・入荷指示エントリー
・出荷指示エントリー

■「知識を実装する」ということ

 誰しも経験を重ねることで、使いまわせるデザインパターンの知識が自然に整理されてくるものだ。それらは設計作業を効率化するために有用なものだが、それで満足してはいけない。なぜなら、デザインパターンが本当に役に立つのは、実装作業を合理化するための枠組みとして開発環境に組み込まれた時だからだ。すなわち、デザインパターンそのものを事前にメタプログラミングしておく――たったそれだけの段取りで、類型的なアプリを個々にプログラミングする手間が要らなくなる。

 ソフトウエア技術者が持つ知識が本当に役に立つのは、それがソフトウエアとして「実装」されたときだ。ただの知識を「社会に影響を与える力」に変換するための優れた手段を我々はすでに手にしている。この立場の有利さを自覚しよう。


*1.このときにこそ、OOP(オブジェクト指向プログラミング)やOOPで言う狭義のデザインパターンを駆使すればよい。これこそが、業務システム開発におけるOOPの正しい使い方であって、個別案件単位での実践にこだわっていてはその可能性を生かしきれない。参考記事「オブジェクト指向とイパネマの娘」

|

« 業務システム向けのデザインパターン | トップページ | 「データモデリングライブ@渋谷(9/29)」のお知らせ »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: デザインパターンそのものをプログラミングする:

« 業務システム向けのデザインパターン | トップページ | 「データモデリングライブ@渋谷(9/29)」のお知らせ »