警告 |
この拡張モジュールは、 実験的 なものです。この拡張モジュールの動作・ 関数名・その他ドキュメントに書かれている事項は、予告なく、将来的な PHP のリリースにおいて変更される可能性があります。 このモジュールは自己責任で使用してください。 |
オブジェクト指向プログラミングでは、簡単なクラス (または インスタンス) を組み合わせてより複雑なクラスを作成するということが 一般に行われます。これは、複雑なオブジェクトやオブジェクト階層を 構築するための柔軟な方法であり、多重継承と同等のことを動的に行う 機能を有します。 クラス(またはオブジェクト)を合成するには、合成される要素の間の 関係により関連(Association)と 集約(Aggregation)の 2 種類の方法があります。
関連は、独立に構築され、外部から 可視の部分を合成したものです。クラスまたはオブジェクトを 関連づける場合、各クラスは関連するクラスへのリファレンスを保持します。 複数のクラスを静的に関連づける場合は、クラスは他のクラスの インスタンスへのリファレンスを含みます。例えば、
例 2. オブジェクトの関連
|
一方、集約では、合成されたパーツのカプセル化 (隠蔽) が行われます。(静的な) 内部クラス (PHP はまだ内部クラスを サポートしていません) を使用することにより、クラスを集約することが できます。この場合、このクラスを含むクラスを通じる場合以外、集約された クラスの定義にはアクセスできません。複数のインスタンスの集約 (オブジェクト集約) は、あるオブジェクトの内部にサブオブジェクトを 動的に作成することを意味し、この過程でこのオブジェクトのプロパティと メソッドを拡張します。
オブジェクトの集約は、(例えば、分子は原子を集約したものであるといった) 包含関係を表す際の自然な方法であり、サブクラスを複数の親クラス およびそのインターフェイスに永続的にバインドすることなく、 多重継承と等価な機能を得るために使用できます。 実際、オブジェクトの集約はより柔軟に使用することができ、集約される オブジェクトで継承するメソッドまたはプロパティを選択することが できます。
3 つのクラスを定義し、各々に別々のストレージメソッドを実装します。
例 3. storage_classes.inc
|
この定義済みクラスを用いていくつかのオブジェクトをインスタンス化し、 集約や集約の解除を行いつつ随時オブジェクトの情報を出力します。
例 4. test_aggregation.php
|
出力内容を見ながら、PHP の集約についての副作用や制限事項を
考えてみましょう。
まず、新しく作成されたオブジェクト $fs
および
$ws
は、期待通りの (対応するクラス定義に
もとづく) 結果を出力します。
PHP では実際のところクラス/オブジェクトの要素についてパブリック/
プライベートの区別はありませんが、集約の際には
クラス/オブジェクトのプライベート要素はアンダースコア文字
("_") で始まるとみなします。
$fs オブジェクト クラス: filestorage プロパティ: data (array) 0 => 3.1415926535898 1 => kludge != cruft メソッド: filestorage メソッド: write $ws オブジェクト クラス: wddxstorage プロパティ: data (array) 0 => 3.1415926535898 1 => kludge != cruft プロパティ: version = 1.0 プロパティ: _id = ID::9bb2b640764d4370eb04808af8b076a5 メソッド: wddxstorage メソッド: store メソッド: _genid |
次に $fs
を WDDXStorage
クラスと集約し、オブジェクトの情報を出力します。
$fs
は今でも FileStorage
のままですが、プロパティ $version
およびメソッド
store() が存在することがわかるでしょう。これらは
いずれも WDDXStorage で定義されているものです。
注意すべき点は、クラスで定義されているプライベート要素は集約されていない
ということです。それらは $ws
オブジェクトの中には
存在します。また、WDDXStorage のコンストラクタも
存在しません。これを集約するのは論理的ではありません。
$fs を WDDXStorage クラスに集約します $fs オブジェクト クラス: filestorage プロパティ: data (array) 0 => 3.1415926535898 1 => kludge != cruft プロパティ: version = 1.0 メソッド: filestorage メソッド: write メソッド: store |
集約処理は、積み重ねていくことが可能です。そこで今度は
$fs
と DBStorage を
集約します。これにより、定義されているすべてのクラスの
保存処理メソッドを使用可能なオブジェクトができあがります。
それを DBStorage クラスに集約します $fs オブジェクト クラス: filestorage プロパティ: data (array) 0 => 3.1415926535898 1 => kludge != cruft プロパティ: version = 1.0 プロパティ: dbtype = mysql メソッド: filestorage メソッド: write メソッド: store メソッド: save |
最後に、プロパティやメソッドを動的に集約したのと同じ方法で、
集約したプロパティやメソッドを解除することも可能です。
$fs
から WDDXStorage
クラスの集約を解除すると、このような結果になります。
WDDXStorage を集約から解除します $fs オブジェクト クラス: filestorage プロパティ: data (array) 0 => 3.1415926535898 1 => kludge != cruft プロパティ: dbtype = mysql メソッド: filestorage メソッド: write メソッド: save |
上で説明しきれなかったことがひとつあります。それは、集約処理の際には
既存のプロパティやメソッドは上書きされないということです。例えば、
FileStorage クラスでは
$data
というプロパティを定義しており、
WDDXStorage クラスでも同名のプロパティが
定義されていますが、このプロパティが
FileStorage のインスタンス化の際に
取得したプロパティの内容を上書きすることはありません。