`Haku a ecrit ca:
Citation : `HackuPourtant, si je regarde ces deux codes :
Code : PHP - Afficher / masquer les numéros de ligne<?php
class Complex {
private $_real;
private $_i;
public function __construct($real, $i) {
$this->_real = (int)$real;
$this->_i = (int)$i;
}
public function add(Complex $c) {
$this->_real += $c->_real;
$this->_i += $c->_i;
}
public function __toString() {
return (string)$this->_real . ($this->_i >= 0 ? ' + ' : '') . $this->_i . 'i';
}
}
$a = new Complex(2, 3);
$a->add(new Complex(5, 0));
?>
<?php
namespace Complex;
function create($real, $i) {
}
function sum($a, $b) {
return array($a[0]+
$b[0],
$a[1]+
$b[1]);
}
function toString($c) {
return (string)$c[0] . ($c[1] >= 0 ? ' + ' : '') . $c[1] . 'i';
}
require_once './Complex.php';
$a = Complex::create(2, 3);
$a = Complex::sum($a, Complex::create(5, 0));
echo Complex::
toString($a);
?>
j'ai l'impression que ni dans l'un ni dans l'autre l'utilisateur n'as besoin de se soucier de la représentation du complexe.
Evidemment, si on avait des structures typées comme les struct du C, le second code serait plus sûr, mais ça c'est une faiblesse de PHP et non du paradigme procédural.
Et par conséquent je pense qu'on peut affirmer que ces deux codes sont aussi cohérents l'un que l'autre.
Ces deux codes montrent bien l avantage de la POO sur le procedural.
L'un des principes de la POO est de cacher a l utilisateur la structure interne, l etat interne de l objet.
Hors la methode procedural fait tout ce qu il ne faut pas faire : recrache l etat interne.
Mais en fait, non, elle ne recrache pas l etat interne, parce que le paradigme procedural ne possede une idee d etat interne qu au niveau des fonctions, contrairement a la POO qui possede cette notion au niveau de la classe.
C'est bien ca qu il faut comprendre:
Procedural : un ensemble de fonctions differentes travaillant sur des donnees. (encapsulation au niveau de la fonction)
POO : des donnees qui forment un tout possedant des methodes, actions. (encapsulation au niveau de la classe)
Code : PHP - Afficher / masquer les numéros de ligne$a = Complex::create(2, 3);
$a = Complex::sum($a, Complex::create(5, 0));
echo Complex::toString($a);
Ta fonction create retourne une array. je peux donc faire cela:
Code : PHP - Afficher / masquer les numéros de ligne$a = Complex::create(2, 3);
$a[0]='string';
//ou encore
array_pop($a);
Le reste de ton code ne marchera plus.
Mais il faut voir que dans un contexte procedural ou la notion d etat interne se situe au niveau de la fonction. Le resultat est coherent.
La fonction manipule la donnee, retourne la donnee. finit. Il n y a pas d idee d'un tout.
La POO, renverse le probleme est reunit toutes les donnees dans une classe et unifie le contexte pour creer un etat interne.
Ainsi ton implementation en classe permet de proteger l encapsulation de plusieurs donnees, chose que le procedural ne peut faire.
L'un des avantages de la POO est donc cette protection de plusieurs proprietes qui une fois reunit donne un objet.
Cette protection est le meme processus que le corps humain: chaque etat interne est relie et permet au tout d avoir des methodes.
Si on saigne, nous n avons pas besoin de dire a notre corps d arreter de saigner. le corps s en occupe pour nous.
La POO offre ce mecanisme.
ensuite, si on regarde ton code procedural:
Code : PHP - Afficher / masquer les numéros de lignenamespace Complex;
function create($real, $i) {
return array($real, $i);
}
Tu as choisi une simple array. En fait, choisir une hash aurait ete encore plus interessant:
Code : PHP - Afficher / masquer les numéros de lignenamespace Complex;
function create($real, $i) {
return array('_real'=>$real, '_i'=>$i);
}
(desole php j ai oublie donc c est peut etre faux)
Pourquoi choisir une hash est plus interessant?
Parce que l on retrouve le meme processus dans d autres languages tel que Perl ou Javascript:
Perl:
Code : Perl - Afficher / masquer les numéros de ligne
sub new {
my ($package) =
shift;
#lorsqu on appelle la fonction on lui met son nom de package qu on recoit en premier argument
my %args = @_; #on recoit les arguments parametres
my $this = {}; #on cree une ref de hash
$this->
{_real
} =
int($args{real
});
$this->
{_i
} =
int($args{i
});
return $this;
#cette ligne n est pas utile mais c est ce que fait perl, il renvoie la hash
}
sub add {
my $this =
shift;
# on recoit l instance actuel de l object, car il s agit d une methode objet
warn 'no,no' if(!
$complex->
isa("Complex"));
$this->{_real}+=$complex->{_real};
$this->{_i}+=$complex->{_i};
}
1;
#dans le code
my $complex = new Complex(real=>3,i=>0);
Je n entre pas dans les details mais il faut savoir que perl ne supporte pas la POO nativement.
Il s agit d un hack en quelques sortes. c est plus bas niveau que php qui contient les mots cles de ce paradigme.
Mais c'est simple : on cree un namespace, cree une hash qui contiendra les proprietes de notre objet et on bless, c est a dire attache le nom du namespace avec celui de la hash, la hash (utile pour l inheritance)
On voit ici qu on est tres pres de ton implementation en php avec le namespace et l utilisation d une array.
Lorsque que quelqu un a dit que tu simulais la POO, il n avait pas tort. Disons que ton code est un avant gout de ce que peut etre la POO.
On peut voir que le code perl a un tres gros defaut : on peut avoir access aux variables internes et donc ce code n offre pas d encapsulation.
A partir de la, differentes methodes sont nees pour permettre d avoir des methodes, proprietes statiques, des methodes, proprietes privees, etc et cela sans aucun
mot cle (utilisation de la reference memoire, utilisation de closure,etc)
C' est interessant car Javascript, bien que reposant sur la POO, offre peu de mots cles permettant l encapsulation:
Code : JavaScript - Afficher / masquer les numéros de lignevar Complex = function (real, i) {
this._real = parseInt(real);
this._i = parseInt(i);
}
Complex.prototype = {
add : function(complex) {
if(!complex isInstanceof Complex) new Error('no,no');
this._real+ = complex._real;
this._i+ = complex._i;
}
var complex = new Complex(3,0);
complex.add(new Complex(3,0));
};
Lorsque pour perl, on doit blesser la hash, javascript le fait pour nous a travers le mot cle new.
Mais il faut savoir que l objet renvoie n est ni plus ni moins qu une hash dote d un nom.
La encore, l encapsulation est inexistante et est souvent simule a travers closure si necessaire.
J espere que l on comprend bien par la que complex.add ou complex->add est tres different de add().
Le premier est un ensemble de donnees dote de methodes, le deuxieme est une fonction travaillant sans contexte autre que le sien.
C est a partir de cette enorme difference que l encapsulation peut naitre.
Finalement de ce concept sont aussi apparus l inheritance et le polymorphisme qui sont a mon avis plus une consequence que le but premier de la POO.
La POO plus lisible que le paradigme procedural? J aurais tendance a dire oui
a partir du moment ou il y a plusieurs proprietes dont l etat
doit etre conserve et
etre cache de l utilisateur.
L example du haut est trival mais des applications de plusieurs milliers de lignes de codes sont autrement plus complexes.
Mais la POO est complexe, surtout si on y ajoute les design patterns qui augmentent le niveau d abstraction.
Quant a dire que la POO est plus naturel que le procedural ( ou sequentiel), je dirai que non.
Lorsque l homme a voulu se proteger d un predateur, il a peut etre pris la pierre la plus grosse et la jete sur la gueule de son adversaire.
Il l a fait deux, trois, quatres fois puis c est rendu compte que la pierre doit etre lourde pour etre efficace mais que le poids
rend la visee et la portee plus difficile.
Alors, il a commence a analiser la situation... quelque chose de fins mais pointus ira plus loin et pourra meme tuer l adversaire qui devient proie.
si on tend une corde et qu on y met un baton, on accroit la portee.
si la tete est un peu plus lourde, on cree un effet d arrondi et d acceleration lors de la descente qui accroit les chances de tuer la proie,etc,etc.
La force de l homme c est sa capacite d analyse et d abstraction.
Mais c est en general apres balbutiements, essais et echecs venus de tentatives empiriques.
Donc le procedural est plus simple a apprehender, plus naturel.
la POO est le resultat d une analyse et d une abstraction, ce qui n est pas a la portee de tous et demande plus d effort.
En tout cas, j avais ete decu de la facon dont Mateo avait introduit le concept de POO dans son cours de C++.
L example etait mal choisi je pense et faisait tomber le tuto dans le commun des cours sur la POO.
Est ce que le PHP meriterait un cours sur la POO? eh bien oui. si Mateo reussi a faire comprendre la POO
de sorte que le tuto soit unique en son genre.
c est parce que les tutos sont limpides que le site du zero a du succes.
Toutes les personnes qui viennent sur ce site ne sont pas tous des debutants.
certains on un niveau faux debutant. Ils commencent a s interesser a la POO mais ne trouve rien de clair.
et la, Mateo pourrait permettre a ces gens de comprendre cette etape.
donc oui, un cours sur la POO par mateo en php me semblerait etre un moyen de faire demarquer encore plus le site.