レコード(リアル・オブジェクト)が入れ替わったことは、
つまり、オブジェクトが異なるので、
異なるプロキシを、生成、破壊するように設計するかもしれませんが、
それは、効率の悪いプログラムになるので、
やめた方がいいでしょう。
オブジェクト全体をコピーする必要があるのは、
ファイル・アクセスのほかに、
別のプロセスや別のマシンに存在するオブジェクトを
ローカルにコピーする場合があります。
いずれも、何らかの媒体を挟んだものになります。
細かい更新要求が多いとき、わざわざ媒体を挟んで更新すると
時間が掛かるので、プロキシを用います。
キャッシュと似た働きをしますが、キャッシュと異なり、
かならずローカル(メモリ)に存在していることが保証されます。
プロキシは、常に存在して多くのオブジェクトの代わりをするだけでなく、
要求があり次第、プロキシを生成するように用いることもあります。
たとえば、文章ファイルを開くとき、画像などの重たいものは、
スクロールして見えるようになってから表示させれば
(画像ファイルのプロキシである、画像オブジェクトを生成すれば)
よいのです。
そうすることで、最初のページを表示するまでの速度を
上げることができます。
たとえば、100×100 個のオブジェクトがあれば、
100×100 のレコード番号配列が二次プロキシになります。
配列に限らず、次に示すようなプロキシ・ツリーを構成するなら、
それぞれのオブジェクトが二次プロキシになります。
/* 地図(親)の二次プロキシ */ struct Map { int map_num; /* 地図レコード番号 */ Area* area[10]; }; /* 地域(子)の二次プロキシ */ struct Area { int area_num; /* 地域レコード番号 */ Map* parent; }; |
二次プロキシは、一次プロキシよりサイズが小さいオブジェクトなので、
すべてのリアル・オブジェクトに対するプロキシ・ツリーを作るのに、
メモリ不足になる可能性は少なくなります。
しかし、そのプロキシ・ツリーを作るために必要なデータ
(レコード番号など)を、
すべて取得できない場合があります。
たとえば、目的のレコードの集合がリンク構造でまとめられていて、
それぞれのリアル・オブジェクトにアクセスしなければならない場合、
アクセス時間が問題になります。
そのような場合は、
ある範囲に限定したプロキシ・ツリーを作ることになります。
たとえば、ビューアなら、
現在ユーザに見せている部分のプロキシ・ツリーを作ります。
(その際、ビューアの構造とデータの構造(プロキシ・ツリー)は、
異なる構成、異なるツリーに別れることに注意してください。
そのあたりの、詳しいことは、Document/View について解説している資料を
参考にしてください。)
たとえば、図形(多角形)を表現するオブジェクトがあるとします。
属性は、頂点の座標の配列だけです。たとえば、
(10, 10), (100, 10), (100, 100), (10, 100)
で、正方形です。
さて、この正方形をたくさん描画することになったら、どうしますか。
1つ目のやり方は、その正方形オブジェクトをたくさん用意して、
すべてのオブジェクトを描画します。
// 正方形オブジェクトを用意する Fig squareA = new Fig( (10, 10), (100, 10), (100, 100), (10, 100) ); Fig squareB = new Fig( (20, 20), (110, 20), (110, 110), (20, 110) ); Fig squareC = new Fig( (40, 40), (130, 40), (130, 130), (40, 130) ); // すべてのオブジェクトを描画する squareA.draw(); squareB.draw(); squareC.draw(); |
2つ目のやり方は、それぞれの正方形オブジェクトを
リアル・オブジェクトとみなして、
プロキシを作成する方法です。
// プロキシ・正方形オブジェクトを用意する Fig squareProxy = new Fig(); // 座標を変えながら描画する squareProxy.exchg( 10 ); squareProxy.draw(); squareProxy.exchg( 20 ); squareProxy.draw(); squareProxy.exchg( 40 ); squareProxy.draw(); |
このやり方は、確かに3つの正方形が描画されますが、
1つのプロキシ・オブジェクトで済むので、メモリの節約になります。
また、リアル・オブジェクトが無いプロキシ
(実体の無いプロキシ)は、パラメータを用いて
座標などの属性を修正します。
もし、リアル・オブジェクトに、
座標のほかに色や模様などの属性があるとしたら、
パラメータに関係ないそれら属性を修正する必要がないので、
処理量が減り実行速度が上がります。
まとめると、
3つの正方形がリアル・オブジェクトに相当するもの、
それらを代用しプログラム中に存在するのが
実体の無い一次プロキシ、
パラメータが実体の無い二次プロキシ(の属性)です。