par
Hywan » 13 févr. 2008, 18:58
En effet, c'est intéressant.
J'ai tenté plusieurs choses rapidement, une des plus concluante est :
<?php
header('Content-Type: text/plain');
abstract class Mere {
protected static $_instance = null;
private function __construct ( ) {
echo 'Bonjour bonjour' . "\n";
}
}
class Fille extends Mere {
public static function getInstance ( ) {
if(parent::$_instance === null)
parent::$_instance = new self();
return parent::$_instance;
}
public function test ( ) {
echo 'Ceci est un test' . "\n";
}
}
$f = Fille::getInstance();
$f->test();
L'inconvénient est qu'on doit exporter la classe getInstance dans la classe Fille. Impossible de déclarer :
abstract public static function getInstance ( );
dans la classe Mere (erreur stricte).
Un coup d'oeil dans le manuel en anglais serait de bonne augure je pense. Apparemment, ça pourrait nous aider, je n'ai lu qu'en diagonal. Une solution doit bien exister.
Sinon comme le proposait Calimero (et c'est pas si bête si on y réfléchit un peu

), serait de faire une classe Factory mais qui fonctionne sur des instances uniques (repère la clé avec get_class()). Ça poserait encore quelques soucis si on veut plusieurs classes Fille, il ne risque d'enregistrer que la classe mère et donc impossible d'avoir plusieurs filles (si on me répond : « bah, faut faire des garçons », je tape à coup de clavier ^^). Tout dépend du comportement que tu veux obtenir au final.
Il reste encore une autre solution, c'est de passer à travers une interface :
<?php
header('Content-Type: text/plain');
interface IFille {
public static function getInstance ( );
}
abstract class Mere {
protected static $_instance = null;
private function __construct ( ) {
echo 'Bonjour bonjour' . "\n";
}
}
class Fille extends Mere implements IFille {
public static function getInstance ( ) {
if(parent::$_instance === null)
parent::$_instance = new self();
return parent::$_instance;
}
public function test ( ) {
echo 'Ceci est un test' . "\n";
}
}
$f = Fille::getInstance();
$f->test();
Plus de soucis de cette façon, tout fonctionne parfaitement. Le seul problème, c'est qu'il faut étendre Mere, et implémenter IFille, c'est pas super super. Et surtout, on laisse le soin au fille de sa déclarer elle-même, pas super non plus.
Ce que je ne comprends pas, c'est pourquoi on peut déclarer une méthode statique dans une interface et pas dans une classe abstraite. Le manuel ne dit rien à ce sujet ?
Àmha, la meilleure solution reste la fabrique à Singleton

.
Ah j'oubliais, toutes les solutions affichent :
évidemment.
En effet, c'est intéressant.
J'ai tenté plusieurs choses rapidement, une des plus concluante est :
[php]<?php
header('Content-Type: text/plain');
abstract class Mere {
protected static $_instance = null;
private function __construct ( ) {
echo 'Bonjour bonjour' . "\n";
}
}
class Fille extends Mere {
public static function getInstance ( ) {
if(parent::$_instance === null)
parent::$_instance = new self();
return parent::$_instance;
}
public function test ( ) {
echo 'Ceci est un test' . "\n";
}
}
$f = Fille::getInstance();
$f->test();[/php]
L'inconvénient est qu'on doit exporter la classe getInstance dans la classe Fille. Impossible de déclarer : [php]abstract public static function getInstance ( );[/php] dans la classe Mere (erreur stricte).
[url=http://www.php.net/manual/en/language.oop5.late-static-bindings.php]Un coup d'oeil dans le manuel en anglais[/url] serait de bonne augure je pense. Apparemment, ça pourrait nous aider, je n'ai lu qu'en diagonal. Une solution doit bien exister.
Sinon comme le proposait Calimero (et c'est pas si bête si on y réfléchit un peu ;-)), serait de faire une classe Factory mais qui fonctionne sur des instances uniques (repère la clé avec get_class()). Ça poserait encore quelques soucis si on veut plusieurs classes Fille, il ne risque d'enregistrer que la classe mère et donc impossible d'avoir plusieurs filles (si on me répond : « bah, faut faire des garçons », je tape à coup de clavier ^^). Tout dépend du comportement que tu veux obtenir au final.
Il reste encore une autre solution, c'est de passer à travers une interface :
[php]<?php
header('Content-Type: text/plain');
interface IFille {
public static function getInstance ( );
}
abstract class Mere {
protected static $_instance = null;
private function __construct ( ) {
echo 'Bonjour bonjour' . "\n";
}
}
class Fille extends Mere implements IFille {
public static function getInstance ( ) {
if(parent::$_instance === null)
parent::$_instance = new self();
return parent::$_instance;
}
public function test ( ) {
echo 'Ceci est un test' . "\n";
}
}
$f = Fille::getInstance();
$f->test();[/php]
Plus de soucis de cette façon, tout fonctionne parfaitement. Le seul problème, c'est qu'il faut étendre Mere, et implémenter IFille, c'est pas super super. Et surtout, on laisse le soin au fille de sa déclarer elle-même, pas super non plus.
Ce que je ne comprends pas, c'est pourquoi on peut déclarer une méthode statique dans une interface et pas dans une classe abstraite. Le manuel ne dit rien à ce sujet ?
Àmha, la meilleure solution reste la fabrique à Singleton ;-).
Ah j'oubliais, toutes les solutions affichent : [code]Bonjour bonjour
Ceci est un test[/code] évidemment.