パターンに要求されるもっとも根本的なことは、問題解決のために利用できることです。ありがちな間違った理解は、技法に名前をつけることと混同していることです。あるいは、「自慢の得意技」を集めたものになってしまったとき、単に技法のカタログにしかなりません。問題解決のために必要な事は、当然ながら「問題点」の抽出と、その問題点の一般化による解決手段の提示が含まれている必要があります。
一方、ちょっと違う見方をすると、どこからが「機能」で、どこからが「パターン」なのかという線引きが分からないということもあります。パターンの世界では、いくつかの要件が組み合わされることの矛盾とそのトレードオフを示すということがパターンに対して要求されるということがよく言われますが、これは1つのヒントです。問題が発生するということは、おそらく要求が単純ではない、つまり、複数の要求があってあちらが立てばこちらが立たずという状況になっているということが言えるわけです。1つの機能でそうした複雑な問題に立ち向かえるかもしれませんが、もし、そうした機能があるとしたら、パターンというよりも、「チョイス」と言えるわけです。FileMakerの世界では、複雑な問題を簡単に解決ことができる「プラグイン」が存在します。では、「プラグイン」はパターンかというと、そうではないと私は思います。単一の機能に帰着するものは、シンプルな、つまり、1対1で事が終わるような問題と解法であり、知っているのかどうか、あるいは挙げられているのかどうかといった、ドキュメントの問題や、記憶しているかどうかといった問題で帰着する訳です。
では、パターンとして論じるものはどんなものがあるのでしょうか。次のような問題があるとしましょう。
最初の問題
顧客管理をしていて、顧客1人が1レコードを確保している(前提)。全社的な情報共有のために、顧客の購買記録と、顧客へのコンタクト記録をデータベースに記録したい(要望)。どのように、ソリューションを作るのが適切か?
FileMakerが得意な人は、もうあれこれ解決策は頭の中を巡るでしょう。もちろん、未確定な要素もあるので、そこはそれぞれです。また、上記の問題は、「問題点」がはっきり分かりません。その上で、まずはこう考えるのではないでしょうか。
- 購買記録、コンタクト記録は、別テーブルを用意してリレーションシップを定義する。いずれも、顧客レコードとは1対多の関係になる
- 特定の顧客に対してのそれぞれの記録は、顧客のレイアウトに、ポータルをそれぞれ配置すればとりあえずは参照できる
- 購買記録は他のテーブルにすでに残している事が判明した(状況の追加)。もともと、顧客とのリレーションシップは存在する
- コンタクト記録の入力をする場合、入力しやすいユーザインタフェースを作らないと、利用してもらえないのではないか
みなさんがさらに考えた事があれば、追加してください。ポイントは、ここまでは、FileMakerの単純な機能についての検討をしたということです。4については、いろいろあるかもしれませんが、要はFileMakerの機能の組み合わせということで帰着できるでしょうし、おそらくユーザ分析しないとこれ以上は議論できません。この状況から、パターンを抽出するのはちょっと無理かなと思います。FileMakerを勉強すれば、迷うところはありません。しかし、打ち合わせをしているうちに、どうもこういう問題ではないかと問題が拡張されてきます。
状況が追加された問題
顧客管理をしていて、顧客1人が1レコードを確保している(前提)。全社的な情報共有のために、顧客の購買記録と、顧客へのコンタクト記録をデータベースに記録したい(要望)。ただし、購買記録はすでにテーブルが存在する。一方、コンタクトと購買の関連を知りたいというのはユーザの要望としてでてきた。どのように、ソリューションを作るのが適切か?
ここでのポイントは、まず、「購買記録」テーブルは存在し、そこにおそらく販売担当者がレコードを追加する仕組みがすでに動いているということが想定され、自由に設計できない範囲が出てきました。一方、コンタクトは初出の機能だとしたら、ともかく、自由に作れそうです。
さて、「コンタクトと購買の関連を知る」というのは一種の非機能要求です。関連って何? 知るというのはどういう状況? ここの解決はユーザインタビューなどの要求工学的手法になるでしょう。開発者と顧客で喧々諤々の議論の結果、「購買情報」と「コンタクト情報」を交えたリストを1人の顧客に対して見えるようにするという基調の機能でいいのではないかとなってきました。大分具体的になってきました。
ここで、「購買記録」「コンタクト記録」が別々のテーブルにあるとして、統合的なリストを作りたいということが要求としてクリアになりました。問題点は「複数のテーブルを1つのテーブルのように扱う」ということでかなり抽象的に表現できそうです。ですが、まずは、FileMaker的にどのように解決できるでしょうか、いくつか案を考えてみます。
- コンタクトも購買テーブルの1レコードとして記録する。つまり、購買の特別な状況としてコンタクトがある。しかし、そうすると、現在の購買テーブルを利用している別のフォームで、コンタクトを見せないようにしないと行けない場合も出てくる。既存の作成物への変更なく終わらせるのはかなり難しい。
- コンタクトテーブルを作るのはもちろん、コンタクトテーブルの1レコードとして購買を記録できるようにする。既存の購買処理には表面的には手を加えなくてもよさそうだが、購買記録を付けたとときに、同時に新しいコンタクトテーブルへのレコード追加も必要となる。スクリプトを加えることで、既存の購買機能はそのままに機能の追加だけでできそうだが、購買機能側に、通販、Webなどなど状況ごとにレイアウトがあったりなんかすると、これは作業としてはコンプリートするのがかなり大変かもしれない。
- コンタクトテーブルは作るが、第三の(第4かな?)、「コンタクト&購買」テーブルを作る。まとめリストはそちらから取得する。この場合、前の2と同様、購買処理時に「コンタクト&購買」テーブルを作る必要があると同時に、コンタクトテーブルについても同じように、別のテーブルにレコードが必要になる。
どうでしょう、一長一短ありますね。まさにここでどうトレードオフをするのかが開発者の腕の見せ所でもありますし、それを成功させるために、より詳細に要求を詰めることもあるかもしれません。ただ、4つ目があるんですが、それは実はパターンそのものなので、以下に記述します。
こうした分析をすると、1つのパターンが見えて来ます。ここでは「種類フィールドを持つテーブル」と名付けます。どういうものかをまずはまとめます。
- 複数の異なる情報を1つにまとめたリストとして表示する必要がある場合に適用可能
- 新規にテーブルを作成し、テーブルの1つのフィールドにそのテーブルの種類を示す「種類」フィールドを確保する。一般には数値フィールドが良く、何らかの方法で、数値と種類の対応はドキュメント化しておく
- 種類A、B、Cがあったとき、それらに必要なフィールドを、すべて新規に作ったテーブルに確保しても良い
- 種類A、Bは新たな項目、一方、種類Cはすでにテーブルで存在する場合、種類Cを記録しているテーブ売るに対する外部キーを、新たに作ったテーブル上に確保する。また、外部キーは種類ごとに用意する
前に示した解決案2と3の折衷案的です。なぜ、3ではないのかというと、3のやり方はオブジェクト指向的な言い方で言えば、抽象クラスに相当するレコードを作る事です。1エンティティに常に2レコードを作るというのは、たとえばポータルなどを含めて、FileMakerではスクリプトを作成する以外に実現のしようがない機能です。そうした仕組みが広範囲に渡りそうなのが解決案3です。ここでは、すでに作ってしまった「購買記録」レコードのメンテナンスのためにスクリプトや改造をがんばって加えるとしても、新たに発生した「コンタクト」情報は素直に作ればいいだろうということで上記のような手法が考えられるということです。
「種類フィールドを持つテーブル」は、さまざまなトレードオフを考える基礎になるということで、パターンであると言えるかと思います。パターンは解決を約束するものではないので、これをベースに考えるということです。この問題で発生した、新たな記録テーブルと、既存の記録テーブルの混在という点についても指針があります。
ここまでがんばって読まれた方だと、容易に分かるかと思いますが、上記のパターンの箇条書きを理解するには、リレーショナルデータベースの基本的なことはみんな知っていないといけません。もちろん当然なのですが、言い換えれば「1対多のリレーションを取る」とか「ポータルに配置する」というのはパターンとは言えないと思います。もっとも、「ポータルフィルタ」は問題解決との関連があるので、パターンの1つと考えています。そこの線引きは難しいですね。一般にパターンカタログでは、パターンだけのカタログになっていますが、これから随時紹介する「FileMakerリレーションパターン」では、前提知識的なものもコンパクトにまとめて行くつもりでもあります。