Manuel PHP
Précédent
Suivant
Avertissement
Ce module est EXPERIMENTAL.
Cela signifie que le comportement de ces fonctions, leurs noms et concrètement, TOUT ce qui est documenté ici peut changer dans un futur proche, SANS PREAVIS!
Soyez-en conscient, et utiliser ce module à vos risques et périls.
En programmation objet, il est courant de rencontrer la combinaison de classes simples (et de leurs instances) en une classe plus complexe.
C'est une strategie habile pour mettre en place des objets complexes, et des hierarchies d 'objets.
Ce système peut fonctionne comme une alternative dynamique à l 'héritage multiple.
Il y a deux solutions pour combiner deux classes, suivant la relation de leurs éléments constitutifs:
L'Association et l 'Aggregation.
Une Association est une combinaison d'éléments construits indépendamment et visibles à l 'extérieur.
Lorsque nous associons des classes ou objets, chacun garde une référence à l'autre partie de l 'association.
Lorsque nous associons des classes statiquement, une classe contient une référence à une instance de l 'autre classe.
Par exemple:
Exemple 1.
Association de classe
?php class DateTime {function DateTime() {/ / constructeur vide} function now() {return date("Y-m-d H:i:s");}} class Report {var $_dt = new DateTime(); / / autres propri eacute;t eacute;s... function Report() {/ / initialisation du code...} function generateReport() {$dateTime = $_dt - now(); / / autre code} / / autres m eacute;thodes...} $rep = new Report();?
Exemple 2.
Association d 'objets
?php class DateTime {/ / identique au pr eacute;c eacute;dent exemple} class DateTimePlus {var $_format; function DateTimePlus($format="Y-m-d H:i:s") {$this - _format = $format} function now() {return date($this - _format);}} class Report {var $_dt; / / Nous allons garder la r eacute;f eacute;rence agrave; DateTime ici / / autre propri eacute;t eacute;s function Report() {/ / initialisation} function setDateTime ($dt) {$this - _dt = $dt;} function generateReport() {$dateTime = $_dt - now(); / / autre code...} / / autres m eacute;thodes...} $rep = new Report(); $dt = new DateTime(); $dtp = new DateTimePlus("l, F j, Y (h:i:s a, T)"); / / G eacute;n eacute;ratino du rapport avec une simple date $rep - setDateTime ($dt); echo $rep - generateReport(); / / plus loin dans le code / / generation du rapport avec une date design eacute;e $rep - setDateTime ($dtp); $output = $rep - generateReport(); / / sauvegarde pour affichage dans la base / /... etc...?
L'Aggregation, d'un autre coté, implique l 'encapsulation et le masquage des parties de la combinaison.
Nous pouvons aggréger des classes en utilisant une méthode statique, grâce aux sous-classes (mais PHP ne supporte pas bien les sous classes), et dans ce cas, la définition de la classe aggrégée n 'est pas accessible, sauf via les méthodes de la classe contenant.
L'aggregation d'instances (aggrégation d'objets) implique la création dynamique de sous-objets à l'intérieur d'un autre objet, et dans le même temps, l'extension des capacités de l'objet principal (en terme de méthodes accessibles).
L'aggrégation d'object est une méthode naturelle pour représenter des relation de type tout-partie (par exemple, une molécule est une aggrégation d'atomes), ou bien peut être utilisée pour obtenir un effet équivalent à l 'héritage multiple, sans avoir à lier plusieurs classes et leurs interfaces.
En fait, les aggrégations d'objets sont plus souples, car nous pouvons alors sélectionner les méthodes et les propriétés qui sont transmises à l 'objet aggrégé.
Nous définissons trois classes, qui implémentent chacune une méthode de stockage différente:
Exemple 3. storage_classes.inc
?php class FileStorage {var $data; function FileStorage($data) {$this - data = $data;} function write($name) {$fp = fopen(name, "w"); fwrite($fp, $this - data); fclose($data);}} class WDDXStorage {var $data; var $version = "1.0"; var $_id; / / variable "priv eacute;e "function WDDXStorage($data) {$this - data = $data; $this - _id = $this - _genID();} function store() {if ($this - _id) {$pid = wddx_packet_start($this - _id); wddx_add_vars($pid, "this - data"); $packet = wddx_packet_end($pid);} else {$packet = wddx_serialize_value($this - data);} $dbh = dba_open("varstore", "w", "gdbm"); dba_insert(md5(uniqid("",true)), $packet, $dbh); dba_close($dbh);} / / m eacute;thode priv eacute;e function _genID() {return md5(uniqid(rand(),true));}} class DBStorage {var $data; var $dbtype = "mysql"; function DBStorage($data) {$this - data = $data;} function save() {$dbh = mysql_connect(); mysql_select_db("storage", $dbh); $serdata = serialize($this - data); mysql_query("insert into vars ('$serdata',now())", $dbh); mysql_close($dbh);}}?
Puis, nous instantion quelques objets issue de ces classes, et nous réalisons des aggrégations et désaggrégations, tout en affichant quelques résultats:
Exemple 4. test_aggregation.php
?php include "storageclasses.inc"; / / quelques utilitaires function p_arr($arr) {foreach($arr as $k= $v) $out[] = "\t$k = $v"; return implode("\n", $out);} function object_info($obj) {$out[] = "Classe: ".get_class($obj); foreach(get_object_vars($obj) as $var= $val) if (is_array($val)) $out[] = "propri eacute;t eacute;: $var (array)\n".p_arr($val); else $out[] = "propri eacute;t eacute;: $var = $val"; foreach(get_class_methods($obj) as $method) $out[] = "m eacute;thode: $method"; return implode("\n", $out);} $data = array(M_PI, "kludge != cruft"); / / cr eacute;ons quelques objets simples $fs = new FileStorage($data); $ws = new WDDXStorage($data); / / affichons des informations sur ces objets echo "\$fs object\n"; echo object_info($fs) ."\n"; echo "\n\$ws object\n"; echo object_info($ws) ."\n"; / / maintenant, quelques aggr eacute;gations echo "\nAggr eacute;geons \$fs avec la classe WDDXStorage\n"; aggregate($fs, "WDDXStorage"); echo "L'objet \$fs \n"; echo object_info($fs) ."\n"; echo "\nAggr eacute;geons le r eacute;sultat avec la classe DBStorage \n"; aggregate($fs, "DBStorage"); echo "L'objet \$fs \n"; echo object_info($fs) ."\n"; echo "\nEt finalement, d eacute;saggr eacute;geons WDDXStorage\n"; deaggregate($fs, "WDDXStorage"); echo "L'objet \$fs \n"; echo object_info($fs) ."\n";?
Etudions maintenant le résultat du script pour comprendre les effets secondaires et les limitations des aggrégations d 'objets en PHP.
D'abord, nous avons créé $fs et $ws et ils fournissent le bon résultat (suivant la définition de leur classe).
Notez que dans le but de l'aggrégation d'objets, les éléments privés d'une classe ou d'un objet doivent commencer par un souligné ("_"), même si il n 'y a pas de distinction réelle entre un objet privé et un objet public.
L'objet $fs Classe: filestorage propri eacute;t eacute;: data (array) 0 = 3.1415926535898 1 = kludge != cruft m eacute;thode: filestorage m eacute;thode: write L'objet $ws Classe: wddxstorage propri eacute;t eacute;: data (array) 0 = 3.1415926535898 1 = kludge != cruft propri eacute;t eacute;: version = 1.0 propri eacute;t eacute;: _id = ID::9bb2b640764d4370eb04808af8b076a5 m eacute;thode: wddxstorage m eacute;thode: store m eacute ;thode: _genid
Nous aggrégeons alors $fs avec la classe WDDXStorage, et nous affichons les informations.
Nous pouvons aussi vior que même si l'objet $fs est toujours du type FileStorage, il a maintenant la propriété $version, et la méthode store(), qui sont définies dans WDDXStorage.
Une chose importante à noter est que les éléments privés n'ont pas été aggrégés, même si ils sont présents dans l 'objet $ws.
Un autre absent est le constructeur de WDDXStorage, qu'il n'est pas logique d 'aggréger.
Aggr eacute; geons \$fs avec la classe WDDXStorage L'objet $fs Classe: filestorage propri eacute;t eacute;: data (array) 0 = 3.1415926535898 1 = kludge != cruft propri eacute;t eacute;: version = 1.0 m eacute;thode: filestorage m eacute;thode: write m eacute ;thode: store
Le processus d'aggrégation est cumulatif, ce qui fait que lorsque nous aggrégeons $fs avec la classe DBStorage, nous générons un objet qui peut utiliser n 'importe laquelle des méthodes de stockage de ces classes.
Aggr eacute; geons le r eacute;sultat avec la classe DBStorage L'objet $fs Classe: filestorage propri eacute;t eacute;: data (array) 0 = 3.1415926535898 1 = kludge != cruft propri eacute;t eacute;: version = 1.0 propri eacute;t eacute;: dbtype = mysql m eacute;thode: filestorage m eacute;thode: write m eacute;thode: store m eacute ;thode: save
Finalement, de la même façon que nous avons aggrégés les méthodes et propriétés dynamiquement, nous pouvons aussi les désaggrégéer.
Si vous désaggrégeons la classe WDDXStorage de l 'objet $fs, nous allons obtenir:
Et finalement, d eacute; saggr eacute;geons WDDXStorage L'objet $fs Classe: filestorage propri eacute;t eacute;: data (array) 0 = 3.1415926535898 1 = kludge != cruft propri eacute;t eacute;: dbtype = mysql m eacute;thode: filestorage m eacute;thode: write m eacute ;thode: save
Un point que nous n'avons pas mentionnéé ci-dessus et que l'aggrégation ne va pas écraser les méthodes ou propriétés déjà existantes dans l 'objet principal.
Par exemple, la classe FileStorage définit une propriété $data, et la classe WDDXStorage Par exemple, la classe FileStorage définit une propriété $data, et la classe WDDXStorage aussi.
Mais cette dernière ne sera pas impliquée dans l 'aggrégation.
Précédent
Sommaire
Suivant
Niveau supérieur