JeuWeb - Crée ton jeu par navigateur
[Résolu] Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Résolu] Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? (/showthread.php?tid=2567)

Pages : 1 2


[Résolu] Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - Sephi-Chan - 14-05-2008

Salut à tous,

Depuis que je me suis mis à l'objet, je n'ai toujours pas trouvé de solution au problème qui va suivre alors que ça me paraît être vraiment élémentaire dans la pensée objet.

Comment faire muter un objet en un autre selon des conditions ? Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ?

Simple problématique que je vais illustrer. Le contexte est celui d'un espace membre. Nous avons une classe Membre et une classe Administrateur (qui hérite de Membre).

La classe Administrateur ajouter des méthodes telles que le bannissement d'un membre ou la suppression d'une news. Dans la base de données, les administrateurs sont différenciés des membres par un champ grade à l'indice plus élevé.

Le but est de permettre à la classe Membre de muter en Administrateur dynamiquement (après même qu'elle a été instanciée) lors de l'appelle à une méthode quelconque. Par exemple, après avoir récupéré les informations du membre, on exécute une méthode qui teste si son rang est membre ou administrateur. S'il est administrateur, l'objet se transforme et obtient donc les méthodes et propriétés de la classe Administrateur.

À ma connaissance, et j'aimerai me tromper, un tel processus n'existe pas. La seule béquille que j'ai trouvé pour compenser cette énorme lacune réside dans le Design Pattern Factory.

Maintenant la question est : est-ce que je me trompe ? Y a-t-il un moyen de faire ce que je cherche ?

Je vous remercie de m'avoir lu et j'attends vos réactions avec impatience.


Sephi-Chan


RE: Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - Shakkah - 14-05-2008

J'ai pas encore vraiment étudié l'objet pour php.
Mais si l'héritage n'existe pas.

Pourquoi tu fais pas un constructeur dans Admin qui prends en entrée un membre du genre:
Code :
class Membre
{
string login;
sting pass;
}

class Admin
{
string login;
sting pass;

Admin (Membre m){
   login = m.getLogin();
   pass = m.getPass();
}

Après comme j'ai dis j'ai pas étudié le php objet donc je sais pas ce qui est possible et l'est pas.


EDIT: En cherchant un peu j'ai trouvé ça
http://www.laltruiste.com/document.php?url=http://www.laltruiste.com/coursphp/objet_heritage.html

php accepte l'héritage mais pas l'héritage multiple , donc je pense que tu peux t'en servir.


RE: Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - NicoMSEvent - 14-05-2008

Ne prends-tu pas le problème a l'envers? Un membre est p-e un admin sans droits... Donc, un membre hérite de certaines méthode d'un admin, et les autres sont masquées...
Enfin, là je chicane :p

Moi ce que je verrais, c'est que tout le monde est (a la base) un membre.
Un "membre" aurait 0..n "droits" (poster, bannir, editer ses messages, éditer tous les messages, ajouter un thread, ajouter une section, ...). Tout dépendrait de la fonction qu'il occuperait


RE: Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - Sephi-Chan - 14-05-2008

Shakkah, je connais PHP mais je parle ici d'une notion (qui n'existe pas à ma connaissance) qui permettrait de faire muter un objet en un autre.

NicoMSEvent, je pense prendre le problème à l'endroit. La pensée naturelle est plus dans l'ajout progressif que dans le raisonnement (tordu ?) du peut-être pas.

Effectivement, dans ce cas de l'espace membre, il vaut mieux avoir toutes les possibilité, et tester à l'appelle d'une méthode si on possède ou non le droit.

Mais ce que je proposais n'était qu'une application. J'ai été confronté à ce problème dans le développement de Seelies : il me fallait savoir quelle classe instancier entre FireSeelie, WoodSeelie, etc. Le problème c'est que pour savoir ça, je devais instancier Seelie. Si j'avais pu ensuite le faire muter en WoodSeelie, ça aurait été bien plus pratique et logique.

j'ai dû recourir à une classe Factory pour résoudre ce problème, et je trouve que c'est plus une béquille imaginé pour compenser une carence dans le langage.


Sephi-Chan


RE: Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - naholyr - 14-05-2008

Comme tu l'as toi-même vu dans tes recherches, c'est le design pattern "Factory" qui résoudra ton problème.

Un objet est d'une classe, s'il change de classe alors c'est un autre objet.
On ne trouve de "mutation" dans aucun des langages que je connais, donc je ne pense pas que ce soit quelque chose auquel tu doives te raccrocher Wink

Si tu veux faire un objet dynamique, je te propose d'utiliser un wrapper :

Code PHP :
<?php 
class Wrapper
{

protected
$wrapped;

public function
getClass()
{
return
get_class($this->wrapped);
}

public function
isA($className)
{
return
is_a($this->wrapped, $className);
}

public function
__call($foo, $args)
{
return
call_user_func_array(array($this->wrapped, $foo), $args);
}

public function
__get($var)
{
return
$this->wrapped->$var;
}

public function
__set($var, $val)
{
$this->wrapped->$var = $val;
}

}

class
GenericMember extends Wrapper
{

public function
__construct($login, $password)
{
$info = self::getInfos($login, $password);

if (!
$info) {
$this->wrapped = new Guest;
} else {
switch (
$info['permission']) {
case
'admin': $this->wrapped = new Administrator($info); break;
case
'moderator': $this->wrapped = new Moderator($info); break;
default:
$this->wrapped = new SimpleMember($info); break;
}
}
}

}


Avec un truc comme ça, tu as ton constructeur générique :
Code PHP :
<?php 
$member
= new GenericMember($login, $password); // cas d'un admin
echo $member->getClass(); // "Administrator"
$member->kick($username); // il a le droit, il est administrateur :)

Tu peux donc jouer avec getClass() et isA() (et éventuellement tout un tas d'autres méthodes utiles au wrapping à ajouter) pour savoir à qui tu as affaire, en revanche l'utilisation de __call() interdit d'utiliser is_callable() ou method_exists() (ces fonctions renverront toujours TRUE, quelque soit le nom de la méthode demandée).





Bon, c'est une méthode. Je pense que le design pattern factory est plus "robuste", et donc un meilleur choix. La seule différence entre un wrapper et un factory c'est la façon de créer l'objet :
Code PHP :
<?php 
// wrapper
$objet = new WrapperClass(...);
// $objet est de la classe WrapperClass, mais dispose de toutes les méthodes et attributs de l'objet wrappé

// factory
$objet = FactoryClass::build(...);
// $objet est directement l'objet de la classe souhaitée
Chacun ses avantages et ses inconvénients, à toi de choisir le bon pattern.


RE: Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - Shakkah - 14-05-2008

Sephi-Chan a écrit :Shakkah, je connais PHP mais je parle ici d'une notion (qui n'existe pas à ma connaissance) qui permettrait de faire muter un objet en un autre.

Dans mon message je parlais pas de tes connaissances mais des miennes dans l'objet en php.

Je t'ai juste proposé une solution possible dans la plupart des techno objet mais j'ai précisé que je ne savais si s'étais réalisable en php. Je parle de ma première idées pas du lien.


RE: Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - naholyr - 14-05-2008

Ah oui, un des avantages du wrapper c'est de pouvoir changer l'objet wrappé à la volée, en ajoutant par exemple une fonction "mutate" :
Code PHP :
<?php 
function mutate($object)
{
$this->wrapped = $object;
}

Pour le coup la mutation devient possible (en apparence) :
Code PHP :
<?php 
$member
= new Wrapper(new SimpleMember($info));
// $member->getClass() == "SimpleMember"
$member->mutate(new Administrator($info));
// $member->getClass() == "Administrator"

En revanche tout ça fait une couche supplémentaire, et - entre autres - ça casse l'auto-complétion dans ton éditeur favori Smile (cela dit c'est aussi le cas du Factory).
M'enfin on n'a rien sans rien.


RE: Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - Cartman34 - 15-05-2008

Personnellement, je créerai une classe mutation qui créerait un nouvel admin.
Ensuite tu récupères toutes les variables du membre et tu les insères à l'admin avec un truc du genre:
Code PHP :
<?php 
foreach($this as $key => $value) {
print
"$key => $value\n";
}
Enfin tu supprimes le membre, ca prend 10 lignes max et tu te prends pas la tete...


RE: Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - keke - 15-05-2008

( /me se gausse en entendant certaines réflexion ... un membre est un administrateur sans droit, il faut un serial factory pour une fonctionnalité évidente, etc ...)
Blague à part, tu pourrais pas faire un constructeur de ta classe (admin) qui prend en argument un objet (membre) et qui recopie un à un tous les champs qui va bien ?

Ainsi le déroulement logique serait :

// on a notre membre toto
membre $toto (paramêtre de création du membre)
// on créé un admin du nom de toto
admin $super_toto ($toto)
// on delete notre membre toto qui n'a plus de raison d'être.
membre ~$toto (paramêtre de destruction du membre)

Après, ne connaissant pas les spécificités de la POO interagissant avec la base de donnée, il me semble qu'il faudrait appeller un constructeur qui ne recréé par tout sur la classe administrateur et un destructeur qui ne supprime rien sur la classe membre.

C'est peut-être très laid, mais c'est ainsi que je procéderais si je devais me retrouver face à ce problème.

kéké


RE: Existe-t-il une notion de mutation d'objet ou d'héritage dynamique ? - Cartman34 - 15-05-2008

keke a écrit :Blague à part, tu pourrais pas faire un constructeur de ta classe (admin) qui prend en argument un objet (membre) et qui recopie un à un tous les champs qui va bien ?

C'est un peu ce que j'ai dis, formulé d'une autre manière...moins détaillée.