XMLスキーマの話で、ボヘミアンと貴族の階級闘争ってご存知だろうか。XML 1.1を巡る「ボヘミアン」と「貴族」の階級闘争
厳密な設計なしにXML文書を書いてもよいとするボヘミアンに対して、厳密な設計なしにXML文書を書いてはいけない、とする貴族。
昔は、厳密な設計とは型の厳密な設計を意味しており、型を厳密に定義するかについては議論が分かれていた。いずれの勢力も、要素と構造を定義することだけは当然のようにしていたとは思う。
現在では、そもそも「ボヘミアンと貴族」なんてもういわなくなったが、両者の違いを敢えて挙げるとすれば、データ表現にスキーマを用いて定義するかどうかだろう。つまり、設計なしにXML文書を書いてもよいとするボヘミアンに対して、設計なしにXML文書を書いてはいけないとする貴族、というのが今の構図だろうか。昔に比べてボヘミアンよりになっていてスキーマはあまり書かなくなってきた。
私はずっとボヘミアンを支持してきたし、自分はボヘミアンの筆頭だと自任していた。
これまでも、重厚長大なものを生みつづける貴族(IBM)たちに刃向かい、お前はハマスか!と怒られつつ、軽薄短小の価値をうったえてきたつもりであった。
しかし、今の時代を考えてみると、どうやら貴族の部類に入ってしまったようである。
Reflexはスキーマを必要とする。必要最低限の設計は、要素の名前と構造を定義することだけであり、Reflexもそれで十分動作するが、スキーマを定義することには変わりない。そうしないと最大のメリットであるデータのポータビリティが失われてしまうのだ。Reflexのモデルでは、Entityのポータビリティは必要条件である。スキーマを定義することで、インターオペラビリティが高められ、ポータビリティが得られて各レイアで開発を分業できるようになる。
ちなみにsMashはずるいことにボヘミアンである。
一例を挙げよう。
def abcdlist = [“a”:1, ”b”:2, ”c”:3, ”d”:4]
というハッシュに対して、次のようなXMLを生成する。abcdlistに追加できる項目の数に上限はなく、ハッシュにおいて、「"e" : 5, "f" :6」が追加されても対応できるが、これをXMLで表現できるのは、以下のように、キーを属性にして動的に追加できるようにしているからだ。
<abcdlist>
<value key=“a”>1</value>
<value key=“b”>2</value>
<value key=“c”>3</value>
<value key=“d”>4</value>
</abcdlist>
Javaでこれを実装すると次のようになる。
Map map= new java.util.HashMap();
map.put(“a”,1);
map.put(“b”,2);
map.put(“c”,3);
map.put(“d”,4);
ところが、これには超えられない壁、RDBが待ち構えている。
例えば、以下のようなSQLを実行する場合、カラムaは静的であることが前提である。
select d from abcdlist where a='1';
keyが動的であることはテーブルに動的にカラムを追加することを意味する。
さあ、どうする?
通常は、テーブルを別けるか、テキストを丸々ストアしてアプリケーションでパースするかのどちらかの対応が必要と思われる。
私なら後者の方法を取るが、RDBを蔑ろにしているようで、これは好きになれない。
いずれにしても、パフォーマンスに影響する大事なところなので、本当に動的項目追加が必要なのかどうか、もういちど設計全体を見直した方がいい。
一方のReflexでは、XMLは以下のようなる。
<abcdlist>
<a>1</a>
<b>2</b>
<c>3</c>
<d>4</d>
</abcdlist>
スキーマであるReflex表現はこうなる。
abcdlist
a&
b&
c&
d&
Java実装部分は次のようになる。
Abcdlist abcdlist = new Abcdlist();
abcdlist.a = new A();
abcdlist.a._$$text = "1";
abcdlist.b = new B();
abcdlist.b._$$text = "2";
abcdlist.c = new C();
abcdlist.c._$$text = "3";
abcdlist.d = new D();
abcdlist.d._$$text = "4";
ポイントは<abcdlist>の子要素に<a>~<d>が静的に定義されているということ。<e>や<f>を追加するにはスキーマの変更が必要になる。
繰り返しになるが、このように静的に定義することで、インターオペラビリティが高められ、ポータビリティが得られるようになる。
ちなみに、Reflexは先ほどのXMLを動的に定義することもできる。属性key付のvalueのListで、*を指定することで0..∞の繰り返しとすればよい。これは先ほどのReflexを使わない例と同様にキーが動的なためテーブルとマッピングすることが困難になる。また、属性を定義しているためJSONと不整合を起こすというデメリットがある。
abcdlist
value@key*&
Java実装部分はちょっと冗長になるが以下のようになる。
Abcdlist abcdlist = new Abcdlist();
abcdlist.value = new ArrayList();
Value value = new Value();
value._$key ="a";
value._$$text ="1";
abcdlist.value.add(value);
Value value = new Value();
value._$key ="b";
value._$$text ="2";
abcdlist.value.add(value);
Value value = new Value();
value._$key ="c";
value._$$text ="3";
abcdlist.value.add(value);
Value value = new Value();
value._$key ="d";
value._$$text ="4";
abcdlist.value.add(value);
ボヘミアンはワーキングプアになりがちである。自由を享受することばかりに関心をもつと後でイタイ目にあう。
貴族になりさえなれば楽をすることができる。
貴族になるにはスキーマを受け入れて動的項目追加をあきらめるだけでよい。(と、悪魔のささやきをしてみる)
この踏み絵を前にして足を出せずに躊躇しているボヘミアンはよくよく考えるべきである。
0 件のコメント:
コメントを投稿