JeuWeb - Crée ton jeu par navigateur
Quand ne doit-on pas utiliser de méthodes ? - 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 : Quand ne doit-on pas utiliser de méthodes ? (/showthread.php?tid=2260)

Pages : 1 2 3


Quand ne doit-on pas utiliser de méthodes ? - Sephi-Chan - 08-01-2008

Salut tout le monde,

Depuis quelques soirées, des questions me trottinent dans la tête à propos de la classe qui gère les Seelies Orphelines (celles qui n'appartiennent encore à aucune communauté) et de certains aspects de la POO de manière générale.
  • Je me demandais si je devais faire une méthode qui vérifiait si la Seelie en question n'était-elle pas déjà dans un Vol par mesure de sécurité ?

    Je m'explique : la classe Orpheline n'est chargée que quand le constructeur de la classe mère Seelie aura récolté les informations sur la Seelies et aura indiqué si la Seelies est Orpheline, Membre d'un Vol ou Fondatrice d'un Vol (pour instancier l'extension de classe adéquate, j'aimerai au passage avoir votre avis sur cette façon de faire). Mais la page d'action du formulaire de création pourrait-être détourné !

  • Dois-je vérifier les données en appelant des méthodes dédiées pour ensuite, si chaque donnée est correcte, appeler la méthode qui va les utiliser ?

    Exemple : J'ai une méthode createFlight qui permet d'initier la création d'un Vol. Dois-je faire dans la page quelque chose comme :
    Code PHP :
    <?php 
    $orpheline
    = new Orpheline($_SESSION['seelie']); // On instancie uniquement si la Seelies est réellement orpheline.
    if($orpheline->isValidName($_POST['name']) && $orpheline->isValidDescription($_POST['description'])){
    $orpheline->createFlight($_POST['name'], $_POST['description']);
    }

  • Ou bien ces vérifications doivent-elle être faîtes dans la méthode createFlight ?

  • Ensuite, je me demandais dans quelle classe mettre la méthode createFlight. En effet, c'est une action qui n'est accessible qu'à une Seelie Orpheline, mais c'est à la fois une action qui concerne les Vols. ?

J'espère que vous pourrez m'aider et vous en remercie d'avance, Wink


Sephi-Chan


RE: Quand ne doit-on pas utiliser de méthodes ? - uriak - 08-01-2008

Déjà d'un point de vue organisation, createFlight doit être une méthode de Flight ou FlightManager, peut importe qui l'appelle, elle concerne le vol, et sera bien mieux ici... la vérification pourrait bien être située dans createFlight, ce serait logique. Mais c'est le cas usuel de la patate chaude en informatique. Dois-je mettre la sécurité en amont en en aval d'une fonction donnée ? Tu peux tout à fait considérer qu'une méthode dois vérifier elle-même sa légalité en fonction d'élements proches de son environnement. Ici ça dépend plus de la situation de la Seelie, que de paramètres internes à Flight, donc il vaut mieux le test du côté Seelie, pour la cohérence.

Ensuite, pour la vérification, c'est un problème qui m'embête aussi, si c'est par post, il faut bien entendu vérifier, et si tu as les infos nécessaire en session ce ne sera pas trop cher, (contrairement à une action dont il faut vérifier la validité en rapatriant des infos en bdd...) l'autre solution étant d'envoyer une information de validité codée, ce qui peut devenir une usine à gaz...

Enfin, il faut penser aux problèmes de l'usage asynchrone. Imaginons un cas bête : la seelies demande à effectuer une action disponible pour qui appartient à un VOL. Entretemps, elle en a été chassée par qui de droit. Paf, sans vérification en BDD, elle va pouvoir faire une action illégale à son corps défendant, puisque ses infos de Session confirmeront que oui, elle est dans un vol (à moins qu'un utilisateur puisse changer la session d'un autre par ses actions.. est-ce seulement possible ?) donc il faut réserver cette approche à tous les éléments dont il est quasi certain qu'ils ne peuvent changer le temps d'une session, sans action volontaire du joueur.


RE: Quand ne doit-on pas utiliser de méthodes ? - pascal - 08-01-2008

principe de conception objet : chaque méthode doit avoir une fonctionnalité unitaire, donc :
_ isValid() va vérifier la validité des données, en utilisant par exemple isValidName() et isValidDescription()
_ createFlight() va seulement créer le vol, pas tester les données. si tu veux savoir si les données sont bonnes tout de même, tu peux ruser.

comment ruser ?
mettre un champ createFlightFlag dans la classe, valant FALSE par défaut. ce champ serait mis à TRUE par isValid(). ce champ serait testé, et s'il vaut TRUE, alors on crée le vol.

A+

Pascal


RE: Quand ne doit-on pas utiliser de méthodes ? - Sephi-Chan - 09-01-2008

Oui, je ne me fierais pas à des sessions "longues durées", vu que les actions sont assez brèves dans le temps.

Pour ce qui est des méthodes où les Seelies agissent sur un Vol, voilà un extrait de la liste des fonctionnalités :

Citation :
  • Seelies Orphelines
    • Fonder un Vol ;
    • Accepter ou décliner l'invitation d'un Vol ;
  • Seelies membres
    • Inviter une Seelie orpheline dans le Vol ;
    • Quitter le Vol ;
    • Poster sur les canaux de discussion du Vol ;
    • Émettre un avis favorable ou défavorable à l'intégration d'une Seelie ;
    • Demander l'exclusion ou la démission d'une Seelie membre ou Fondratrice ;
  • Seelies Fondatrices
    • Hérite des possibilités des Seelies membres
    • Émettre un avis sur l'exclusion ou la démission d'une Seelie ;
    • Demander un remplacement à la place de Fondatrice (nécessaire pour quitter un Vol) ;

Je pense donc que donner des actions sur les Vols aux différents classes filles (Orpheline, Membre ou Fondatrice) de Seelies est tout à fait justifié. Les classes des Vols seront, à priori, plus abstraites, dans le sens que ce ne sont pas les joueurs qui les déclencheront (pas toutes, du moins).

Merci de m'éclairer en tout cas, Smile


Sephi-Chan


RE: Quand ne doit-on pas utiliser de méthodes ? - uriak - 09-01-2008

Pascal, tu devrais préciser dans quelle classe on met ce flag. Plus qu'une question d'unité, je suis pour qu'une méthode puisse vérifier sa validité au regard des données internes à sa classe. Si par exemple tu tentes d'accéder à un élément impossible (index trop grand), la méthode peut gérer d'elle-même cette contradiction et répondre de manière appropriée. Par contre elle n'a pas à vérifier que tel élément avait le droit de l'appeler.

Pour tes fonctions, il faut séparer les méthodes entre celles agissant sur la seelie et celles sur le vol. Si par ex en quittant un vol, tu changes le total des membres du vol (ok c'est une info théoriquement définie par la table des Seelies, mais bon, on peut vouloir éviter la requête...)
il faut donc une méthode quitter vol pour la seelie, qui va elle-même appeler quitter pour la classe VOL, en signalant son identifiant s'il faut récupérer des infos spécifiques à la seelie


RE: Quand ne doit-on pas utiliser de méthodes ? - pascal - 09-01-2008

on met le flag dans la classe qui gère le vol.

il y a 3 rôles en fait, concernant le vol :
_ orpheline : pas de vol
_ membre : en lien avec un vol
_ fondateur : membre + fondateur

je pense que la seelies devrait avoir un champ vol, membre de la classe vol. et tout ce qui gère le vol se trouverait dedans.

comment initialiser ce champ dans la seelies ?
_ on peut avoir un champ dans seelies indiquant le rôle, et selon ce rôle, la possibilité d'exécuter ou non certaines méthodes ( bof bof )
_ selon le rôle récupéré à la création de l'objet seelies, on instancie vol en l'une ou l'autre des classes spécialisées en vol ( orpheline, membre ou fondateur ), classes héritant d'une classe vol de base ou implémantant une interface vol

pour le code actuel de ton script, on peut l'améliorer pour profiter des concepts objets :
principe objet : on programme en objet pour se simplifier la vie et gagner du temps ( et ainsi faire des trucs de geeks, comme boire du café, baston de missiles USB et intégrale X-files )

ce qui fait perdre du temps, c'est le changement. ce qui peut changer pour le vol ?
on peut imaginer un droit d'inscription à un vol, une sorte de club privé... dans ce cas on doit modifier le source du script :
Code PHP :
<?php 
//code original
$orpheline = new Orpheline($_SESSION['seelie']);
if(
$orpheline->isValidName($_POST['name']) && $orpheline->isValidDescription($_POST['description'])){
$orpheline->createFlight($_POST['name'], $_POST['description']);
}
on doit ajouter un champ ressource, donc ajouter au script :
_ $orpheline->isValidRessource($_POST['ressource']) dans le test
_ $_POST['ressource'] en paramètre de createFlight
( tout ça en plus de changer le formulaire et la classe )

on va faire un code qui résiste au changement : on ne devra pas changer le script si on ajoute un champ.
ce qui change : le champ en plus, d'où test en plus et paramètre en plus
ce qui ne change pas : on traite toujours un tableau, en l'occurence $_POST

=> on fabrique des méthodes utilisant des tableaux, les index seront traités dans la classe
=> on fabrique un test générique : isValid( $array ), les tests en plus lui seront ajoutés dans la classe

on obtient le script :
Code PHP :
<?php 
//code plus évolutif
$orpheline = new Orpheline($_SESSION['seelie']);
if(
$orpheline->isValid($_POST) ){
$orpheline->createFlight($_POST);
}

pour que la méthode de création vérifie la validité des données, je vais détailler l'idée du flag :
_ c'est un membre de la classe vol, par défaut il vaut FALSE
_ si la méthode isValid() indique TRUE = données valides, alors elle passe le flag à TRUE, sinon elle le laisse à FALSE
_ la méthode createFLight() ressemble alors à :
Code PHP :
<?php 
function createFlight( array $arr )
{
// test qui veut dire : si on a utilisé isValid et que les données sont valides
if( $this->createFlightFlag == TRUE )
{
// code pour creer la vol
}
}

A+

Pascal


RE: Quand ne doit-on pas utiliser de méthodes ? - uriak - 09-01-2008

théoriquement l'objet se suffit à lui-même et propose des méthodes destinées à son maniement.

l'objet vol doit permettre de gérer tous les aspects d'un vol, et son utilisation que ce soit par des classes de joueurs, un outil d'administration ou un script CRON. La méthode creer_vol en soi est un constructeur, qui demandera de renseigner les éléments principaux. Mais il n'y a pas de logique à ce qu'elle vérifie, elle la légalité de son appel, par une seelie ou quiconque. c'est la méthode creer_vol de la Seelie, qui doit le faire. (évidemment, on va éviter les homomnymes) après tout, c'est bien la classe Seelie qui connaît ses propres autorisations. Evidemment, s'il y a des dizaines de types de Seelie, il peut être intéressant de mettre côté vol un tableau d'attributs/autorisations : tout comme un fichier à ses attributs écriture/lecture/suppression et non pas chaque utilisateur une liste des fichiers autorisés.

Si j'étais en C++, j'aurais en gros un FlightManager avec son vector de Flight et ses attributs d'accès et création à lui. On y accederais par singloton. Il aurait une méthode AddNewFlight()... La classe LoneSeelie aurait la méthode CreateFlight() qui ferait FlightManager::getSingleton().AddNewFlight(this)


RE: Quand ne doit-on pas utiliser de méthodes ? - pascal - 09-01-2008

oxman a écrit :Je n'y connais rien en POO, mais ça me semble une absurdité de devoir appeler une méthode de vérification des données avant.

A mes yeux c'est createFlight qui doit s'en occuper.

je vais expliquer ce qui se cache derrière tout ça :

alors oui, complêtement d'accord, il faut vérifier les données avant de les utiliser. mais non, ce n'est pas absurde de séparer les choses.

en séparant, on peut faire évolutif : on n'a pas de grosses méthodes fourre tout, mais de petites méthodes ciblées, plus courte, plus simples à appréhender 6 mois après qu'un gros paté de code

en séparant et spécialisant les méthodes, on peut leur appliquer des tests unitaires. et avoir moins de bugs en production à priori, une confiance accrue dans son code, un cadre pour vérifier les régressions lors de modifications du code.

et en séparant vérification et enregistrement de données, on a un script qui ressemble à du pseudo code :
si les données vérifiées sont valides,
alors j'enregistre
sinon, je signale les erreurs

si on fait une seule méthode qui vérifie et enregistre, comment passer au "else" qui signale les erreurs ?

A+

Pascal


RE: Quand ne doit-on pas utiliser de méthodes ? - pascal - 09-01-2008

oxman a écrit :Je ne sais pas, mais il doit y avoir plus propre je pense Big Grin

je te laisse le soin de proposer et d'expliquer .

A+

Pascal


RE: Quand ne doit-on pas utiliser de méthodes ? - uriak - 09-01-2008

Tout dépend de ce qu'on entend par propre... le problème ici du php, c'est que qu'étant asynchrone, le simple fait d'appeller la méthode CreateFlight n'est pas un gage d'autorisation à le faire.

Je plussoie pour la vérification unitaire en fait. Une sorte de CheckState() à appeller avant execution d'une action par la Seelie. Et qui appelle ce qu'il faut si on constate que la Seelie n'est pas ce qu'elle prétend être. La seule chose que je trouve dommage c'est de devoir faire une requête pour vérifier un élement, on a l'impression de toujours faire les choses en double :
requête pour présenter une option, une requête pour vérifier qu'on avait le droit à l'option...