[POO] : Une calculatrice comme exercice de pratique.
Bonjour,
Cela fait quelque temps que je tente de mettre à la POO. Le pas est fait et j'ai donc commencé à lire les tutoriels de POO proposés sur ce site. La compréhension est assez facile, le vocabulaire commence à rentre, mais je manque de pratique. Ainsi, je me penche sur l'exemple de la calculatrice : un objet de tous les jours (enfin, pour les étudiants), où les attributs sont des nombres et les méthodes sont l'addition, la soustraction...
Je tiens à préciser néanmoins, que cette calculatrice fera pour le moment que l'addition comme calcule, avec seulement deux nombres. C'est une calculette ultra basique, mais qui pour moi me permet de voir si j'utilise bien la POO, dans la bonne logique. Voici donc ma class Calculatrice :
<?php class Calculatrice{ // Attributs public $nombre1; public $nombre2; public $resultat; // Méthodes public function __construct($nombre1,$nombre2) { $this->nombre1 = $nombre1; $this->nombre2 = $nombre2; } public function additionner() { $this->resultat = $this->nombre1 + $this->nombre2; return $this->resultat; }} $calculer = new Calculatrice(3,4);echo $calculer->additionner(); ?>
Bien entendu, le code présent est fonctionnel, je l'ai testé au préalable. Ce que je souhaite, c'est savoir si ce code est correct, bien indenté, respect la bonne syntaxe... Vous l'aurez compris, je souhaite coder proprement.. Bref.
J'ai par contre deux questions qui me trotent avec ce petit bout de code : si vous regardez la ligne 24, j'instancie ma class en mettant deux paramètres (les deux nombres pour le calcul), et qui en gros, me servira pour le _construct(). Est-ce que c'est mieux de le mettre au_construct() ou à la fonction additonner() ? Je ne sais pas ce qui est le mieux, donc une toute petite explication serait la bienvenue ! De plus, j'utilise aussi le mot clé "public" pour mes attributs et mes méthodes (pour intégrer un maximum de chose que j'ai lu du cours). Je me demande si on peux mettre à "private" les attributs, et laisser la fonction additionner en "public" (car sinon je pourrais pas l'appeler en dehors de ma class)
Si mon code vous parait logique pour de la POO, je continurai sur ce même topic à l'améliorer, en détaillant à chaque fois ce que j'ai rajouté ou modifié, ou en posant mes diverses questions sur cette class ou ce que je prévoirai.
Merci d'avance pour vos réponses.
Réponses apportées à cette discussion
Bonjour Jérémy,
Ton code n'est pas mal mais il peut largement être amélioré. Voici comment je procéderai personnellement :
<?php class Calculatrice{ /** * Résultat des calculs * * @var double * @access private */ private $_resultat; /** * Constructeur * * @param void * @return void */ public function __construct() { $this->_resultat = 0; } /** * Retourne le résultat * * @param void * @return double */ public function getResultat() { return (double) $this->_resultat; } /** * Réinitialise la calculatrice * * @param void * @return void */ public function init() { $this->_resultat = 0; } /** * Additionne deux nombres * * Si un seul nombre est donné, il est aditionné au résultat * * @param double $a * @param double|null $b * @return double resultat de l'opération */ public function additionner($a, $b = null) { $a = (double) $a; if(null !== $b) { $this->_resultat = $a + (double) $b; } else { $this->_resultat += $a; } return $this->getResultat(); } /** * Multiplie deux nombres * * Si un seul nombre est donné, il est multiplié au résultat * * @param double $a * @param double|null $b * @return double resultat de l'opération */ public function multiplier($a, $b = null) { $a = (double) $a; if(null !== $b) { $this->_resultat = $a * (double) $b; } else { $this->_resultat *= $a; } return $this->getResultat(); }} $c = new Calculatrice();echo $c->additionner(10,45); // retourne 55echo $c->multiplier(2); // retourne 110echo $c->additionner(10) // retourne 120$c->init();echo $c->multiplier(4); // retourne 0echo $c->multiplier(4,3); // retourne 12echo $c->additionner(12); // retourne 24 ?>
Je pense que tu devrais d'inspirer de ça :)
Bonne continuation,
Hugo.
Mmmh.. pas bète ton code..
J'ai quelques questions à te poser sur ton code : il y a-t-il une différence entre != et !== (je crois que le deuxième signifie différent et de même type.. mais pas sûr) ?
L'instruction présene dans les méthodes _construct() et init() sont différentes, mais on le même but non ? (celle de à zéro)
Dans ton code, tu mets des commentaires pour chaque méthode et même pour l'attribut. Est-ce nécessaire de le mettre dans mes futures codes ? Personnellement, je trouve que c'est intéressant, surtout quand on lit le code de quelqu'un d'autre, ça permet de savoir quel type de donnée entre et sort.
Etant donné qu'on écrit directement les nombres dans le code source pour calculer, j'aimerai bien passer par un formulaire pour que le client entre directement les nombres et le type de calcul à réaliser. Je pense qu'on peut aussi utiliser la POO pour faire ce formulaire :
_ Attribut : les champs (nombre et opération).
_ Méthode : là je bloque un peu.. car si j'ai bien compris, les méthodes permettent de faire des actions bien précise, et si je pense au formulaire pour la calculatrice, l'action aurait été de calculer les nombres selon l'opération choisie. Ainsi, la class Formulaire appélerait la class Calculatrice pour réaliser le calcul. (j'hésite avec l'utilisation de l'héritage)
Q'en penses-tu ?
Mon formulaire pourrait très bien avoir deux champs pour les deux nombres, et une liste déroulante pour le choix de l'opération. On valide pour calculer, et lors de l'affichage, on peut soit faire un autre type de calcul, soit on rajoute une opération au résultat précédent. Ainsi, en reprenant ta class (bien mieux que la mienne, je doit l'avouer) peut répondre à plusieurs de mes demandes.
Voilà, en attendant ta réponse, je vais commencer à réfléchir sur mon code. Merci pour ta réponse précédente.
PS : A la fin de ton code, tu as mis :
echo $c->additionner(10,45); // retourne 45
Alors que 10+45=55 ! ^^
J'ai quelques questions à te poser sur ton code : il y a-t-il une différence entre != et !== (je crois que le deuxième signifie différent et de même type.. mais pas sûr) ?
Oui il y'a un test sur le type en plus. De ce fait je m'assure que c'est bien la constante null et pas la chaine 'null' qui se trouve dans la valeur de la variable. Tu peux aussi faire if(is_null($var)) si tu ne veux pas risquer de te tromper en écrivant les signes =
L'instruction présene dans les méthodes _construct() et init() sont différentes, mais on le même but non ?
Oui je me suis planté. Tu peux choisir l'une ou l'autre des deux valeurs. Mais le zéro à l'avantage de t'assurer que si tu as une opération à faire, elle se fera avec 0 et non avec null. Donc tu ne risques pas de résultats improbables.
Dans ton code, tu mets des commentaires pour chaque méthode et même pour l'attribut. Est-ce nécessaire de le mettre dans mes futures codes ?
C'est une bonne habitude (pratique même) que j'ai prise et que je fais à chaque fois que j'écris un code orienté objet ou même une fonction utilisateur basique. Je les ai volontairement mis dans la classe Calculatrice pour t'habituer (ainsi que les autres lecteurs qui liront ce topic) à faire de même. Et si tu fais attention, dans le chapitre sur la POO, les classes sont elles aussi documentées de cette manière. L'avantage de cette syntaxe (dite Javadoc car issue du langage Java) c'est qu'elle est reconnue par de nombreux développeurs et qu'elle permet ensuite d'automatiser la génération de documentation technique de code avec des outils comme PHPDocumentor. Même pour des projets solo, c'est une bonne pratique à avoir que de documenter son code. Je te mets au défi de te rappeler de chacun des types d'entrée / sortie des arguments de tes méthodes dans 6 mois quand tu replongeras dans ton code.
Ainsi, la class Formulaire appélerait la class Calculatrice pour réaliser le calcul. (j'hésite avec l'utilisation de l'héritage)
Surtout pas d'héritage car un formulaire n'est pas une Calculatrice ni l'inverse, ça n'a pas de sens. En revanche, tu peux simplement faire un truc du genre :
<?php // Initialisation des variables$a = 0;$b = 0;$r = 0;$o = '+';$operations = array('+','-','*','/'); // Test du formulaireif(!empty($_POST)){ if(isset($_POST['a']) && is_numeric($_POST['a'])) { $a = (double) $_POST['a']; } if(isset($_POST['b']) && is_numeric($_POST['b'])) { $b = (double) $_POST['b']; } if(isset($_POST['o']) && 1 === strlen($_POST['o'] && in_array($_POST['o'], $operations)) { $o = (string) $operations[$_POST['o']]; } try { // Création de la calculatrice $c = new Calculatrice(); // Test de l'opération switch($o) { case '+': $r = $c->additionner($a,$b); break; case '-': $r = $c->soustraire($a,$b); break; case '*': $r = $c->multiplier($a,$b); break; case '/': // A toi de vérifier dans la méthode que $b ne vaut pas 0. // Si tel est le cas tu lances une exception $r = $c->diviser($a,$b); break; default: trigger_error('Opération non implémentée', E_USER_ERROR); break; } } catch(Exception $e) { die($e->getMessage()); } // Affichage du résultat echo 'Résultat : ', $r;}?>
A toi de faire le formulaire HTML avec les 3 champs + bouton submit.
++
Hugo.
PS : merci de m'avoir corrigé mon calcul lol.
Ok, merci pour toutes ces informations. Pour les commentaires, je suivrai tes indications, et puis, je trouve également que c'est plus clair et qu'en plus, ça me forcera à savoir quel type je met dans la méthode ou attribut et qu'est-ce qui ressortira (excellent quand on doit choisir les fonctions natives de php pour sécuriser son code) !
Pour l'histoire d'hériter mes class... j'avoue que c'est un peu illogique ce que j'ai dit... je souhaitais juste m'aider en prenant une méthode de la class Calculatrice... Bref, c'est pas comme ça qu'il faudrait que je réfléchisse, mais plutôt en tant qu'objet.
Par contre, en étant entièrement reconnaissant des codes que tu me donnes pour que je comprenne la POO, j'aimerai plutôt que tu m'indiques qu'est-ce qu'il serait mieux que je fasse, des indices, ou seulement le nom des fonctions. Je te demande cela simplement pour que je me force à réfléchir, et non à "pomper" ton code et à réfléchir dessus. Mais je suis quand même très reconnaissant de ces codes. Merci.
Bon, sur ceux, je vais lire attentivement tes deux codes, réfléchir et comprendre comment ils fonctionnent, et encastrer le formulaire. Au fait, j'ai parlé de créer une class Formulaire pour utiliser ma calculatrice, même si j'ai vu que tu proposais une série de test pour vérifier le formulaire. Penses-tu que le formulaire peut être une class en utilisant les attributs et méthodes dans ma réponse précédente ?
Merci encore pour tes réponses.
PS : Pour la correction du calcul dans ton code, tu as corrigé qu'un bout, car 55*2 != 90 et idem pour l'autre calcul (avec le +10)... bon j'arrête de te corriger, promis ! ^^ (arf, en même temps, dans ton post précédent, tu as cité 2 de mes phrases, et j'ai aussi fai 2 fautes... ahalala la relecture) lol.
PS 2 : Petit détails complètement inutile, dans les commentaires de tes tutoriels, mon pseudo était Jérémy_B... je pense que tu avais fait le rapprochement avec ce nouveau pseudo (car maintenant inscrit) ! Bon, je l'avais dit, détail totalement inutile.. :p
j'aimerai plutôt que tu m'indiques qu'est-ce qu'il serait mieux que je fasse, des indices, ou seulement le nom des fonctions. Je te demande cela simplement pour que je me force à réfléchir, et non à "pomper" ton code et à réfléchir dessus
Pas de soucis je le ferai à l'avenir ;)
Penses-tu que le formulaire peut être une class en utilisant les attributs et méthodes dans ma réponse précédente ?
Tu peux faire une classe pour créer, filtrer et valider ton formulaire mais ce ne sera pas à elle d'appeler les méthodes de ta classe Calculatrice. Je t'invite à consulter et utiliser le composant Zend_Form du framework Zend.
++
PS 1 : je corrige les calculs ^^
PS 2 : oui j'avais fait le rapprochement :)
Est-ce que quelqu'un d'entre vous peux me dire ce que signifie Le double et le string dans les code, est que c'est une définition de type de variable ?
ex:
$a = (double) $a; //decimal ??
i hope your post more detial, anyway! it is very nice! cheap ugg boots for sale
Your profession of choice is telling you of knowing and possibilities. uggs outlet stores