PHP POO: Questions existencielle de débutant

PHP POO: Questions existencielle de débutant - PHP - Programmation

Marsh Posté le 03-04-2008 à 20:50:34    

Bonsoir à tous!
 
Voilà, je suis débutant en PHP et en programmation objet et j'ai commencé à programmer un carnet d'adresses en PHP/MySQL orienté objet (pour mon propre apprentissage). Seulement voilà, je n'arrive pas à savoir comment découper et organiser mon application. J'ai bien regardé du côté de MVC, mais c'est très théorique et je n'arrive pas à l'appliquer à mon cas.
 
Je ne sais pas trop comment organiser mes classes, et surtout les méthodes associées, notamment l'accès à la base de données et l'affichage.
 
J'oscille constamment entre plusieurs organisations sans avoir de fil directeur qui puisse me dire "c'est celle là qui est la mieux adaptée", c'est pourquoi je m'adresse à vous, pour que vous me disiez ce que vous en pensez, et n'hésitez pas à me faire des remarques et à me donner des conseils car quand on débute, on ne connait pas tous les tenants et aboutissants (ce serait dommage de partir dans la mauvaise direction ou de prendre de mauvaises habitudes dès le début!)
 
Au début, j'avais une classe Contact qui avait tout, du style:
Classe: Contact
Champs: $last_name, $first_name etc.
Méthodes:
->setLastName($last_name)
->getLastName()
...
->getContactBase($database)
->addContactBase($database)
->deleteContactBase($database)
->displayContact()
 
Mais bon, l'accès à la base de données, l'affichage html, tout était dans la même classe. J'ai trouvé ça trop fourre-tout. Et comme je voulais aussi pouvoir avoir la liste de tous les contacts, j'ai réorganisé au final comme ça:
 
Classe: Contact
Champs: $last_name, $first_name etc.
Méthodes:
->setLastName($last_name)
->getLastName()
...
 
Classe: AddressBook
méthodes:
->getContact($id)
->getContactList()
->addContact($contact)
->deleteContact($id)
 
Classe: View
Méthodes:
->displayContactQuickInfo($contact)
->displayContactDetails($contact)
->displayContactList($list)
 
Ce qui me parait avoir plus de sens: les entrées et sortie de AddressBook ne sont alors que des objets définis dans mes classes, et la BDD est invisible depuis l'extérieur de AddressBook (tous les accès à la BDD se font dans AddressBook).
Je n'utilise que MySQL, donc les méthodes de AddressBook contiennent directement des requêtes SQL (plus tard je réfléchirai à comment rendre ça indépendant de la BDD)
 
Il vaut mieux faire une classe d'affichage associée à chaque entité ou bien une classe générique View qui prend tout? D'un autre côté je trouverais ça bizarre de faire une classe ContactView et AddressBookView séparées... (je vois pas trop l'intérêt)
 
Voilà mes premieres interrogations, j'en ai d'autres (mais peut être que vos commentaires y répondront!)
 
Merci!
 
/glattering

Reply

Marsh Posté le 03-04-2008 à 20:50:34   

Reply

Marsh Posté le 04-04-2008 à 00:59:12    

avant de penser a organiser tes classes, commence par faire (et surtout) bien penser ta ta base de données, en mettant les bons champs dans les bonnes tables, ainsi que tout ce qui répartitions, liens, etc. entre les tables de ta base, une fois cette étape passé, tes classes se dessinneront plus facilement :)
 
pour les connexions a la base, essaye d'utiliser quelque chose qui existe deja, genre une classe d'abstraction de la BD ce qui t'evitera tout le tralala des requetes sql etc. mais tu peux très bien t'en créer une a toi, après tout tu le fait pour apprendre :) et certes réinventer la roue et toujours a éviter en prog mais pas quand on veut apprendre, en tout cas c'est mon avis :)
 
mais je pense que tu trouvera pas mal de réponses a tes question en lisant un peu de doc sur les MVC, il y a un topic sur le forum avec pas mal de bons exemples mais bon c'est un peu éparpillé dans les pages du topic donc assez difficile a trouver.

Reply

Marsh Posté le 04-04-2008 à 09:25:01    

Yop

 

Ca peut paraitre con, mais je le dit tout de même : un objet ne doit pas avoir plus d'une raison de changer.

 

Typiquement ton contact c'est quoi ??

 

Contact = {nom, prenom, adresse, get(), set()} ou get() et set() sont du style $this->nom = $param ; return $this->nom

 

AdressBook c'est quoi ??
--
Composite:
Un composite avec quelques méthodes : tu auras toujours besoin d'un composite pour stocker les donnes de ton modele. Donc autant le faire de suite.
Petit indice, sur un MVC ya souvent un composite qui circule entre tes 3 ouches.
Donc une classe abtraite implementant composite que tu etendras pour obtenir ton adressBook.
--

 

Autre partie l'access au donnees. Ce n'est pas ton contact qui lit, ecrit les donnes. Entre ta base physique et ton modele tu trouveras des DAO : objets specialises pour l acces aux donnees.

 

Si ya une chose a laquelle tu dois reflechir c'est la communication entre ton modele et la DB. Decouplee a point, mais pas trop sinon tu finis sur des conneries de fichiers XML ou autres pour faire le lien. Tu dois pouvoir pondre quelquechose de mieux que Active Record et un peu moins complet que le table data gateway pattern.

 

@naeh , les classes d'abstraction DB ne servent pas a grand chose et ne sont pas une priorite. Ecrire une requete en 3 fonctions ou en une c'est purement de l'optimisation.

 


Voila gl


Message édité par supermofo le 04-04-2008 à 09:32:06

---------------
Echange de 3000+ liens PR 3 -> 5, me pm urgent !
Reply

Marsh Posté le 04-04-2008 à 11:13:40    

Tout d'abord merci pour vos réponses.
Alors pour ce qui est de l'organisation de la BDD, je pense que c'est pas mal, j'y ai beaucoup réfléchi.
J'ai une table par objet/classe de données: une table Contact, une table Home, et une table living qui associe un contact avec une maison. (j'ai d'autres tables mais dans le meme style, l'idée est là).
Ensuite j'ai donc une classe Contact, et une classe Home.
supermofo:
Contact contient:
protected $id (id dans la base)
protected $last_name
protected $first_name
protected $home = new Home()
et oui, les méthodes associées pour changer ou récupérer les infos du contact (y'a des méthodes pour ajouter/supprimer des maisons (un contact peut avoir plusieurs maisons dans ma base)).
 
Addressbook c'est un peu fouilli.
A l'état actuel, ca contient:
protected $language
protected $theme
protected $database = new MySQLBase();
protected $user
 
méthodes:
addContact($contact) qui ajoute un contact dans la base (ajoute les infos du contact dans la table contact et les maisons dans home et ajoute le lien contact<->maison dans living pour chaque maison)
deleteContact($id)
updateContact($contact)
 
où MySQLBase est une classe qui contient des méthodes (connect, disconnect, execQuery etc).
Sur ce point c'est très confus, je ne sais pas si je dois instancier la database a l'exterieur de addressbook et la passer en paramètre pour les méthodes getContact, deleteContact etc.
 
Pour le composite j'ai pas compris ce que c'était en fait, son rôle, ce qu'il instanciait, contenait etc... un ex?
 
 
Arg, j'ai plein de questions, plein de points flous... mais c'est dur à expliquer.
notamment sur la présentation, quels objets créer?
j'ai créer des classe tableaux, images, liens, page, menu, header etc, comment gérer leur affichage? comment organiser tout ca?
 
Je suis tenté de vous envoyer mon code, mais ca fait un peu bourrin et bcp d'un coup, et c'est ptête pas très intéressant pour vous!!!! :-/


Message édité par glattering le 04-04-2008 à 11:21:27
Reply

Marsh Posté le 04-04-2008 à 11:58:45    

Au sujet de MVC j'en suis page 8 du topic dédié...
arg

Reply

Marsh Posté le 04-04-2008 à 15:22:30    

Pour la presentation:

 

- ta page au rendu est decoupe en zone (header, menu, contenu, footer)
- chacune de ces zones est capable de deplier les donnees qu'elle recoit du modele (dans ton controller, il faut definir ta vue comme une composite de view). L'ensemble est deplie avec un parcours de ta composite view.
- les classes que tu decris liens, page, images sont des helpers pour ta view : de l'optimisation pas du design :)

  

Pour addressBOOK:

 

Il faut découpler ton modèle a tout prix !
AdressBOOK = {contact1,contact2,contact3,contact4}
Pas de requete SQL dans contact, ni adresseBook.

 


ca vaut le coup

 

google => table data gateway pattern

 



Message édité par supermofo le 04-04-2008 à 15:29:21

---------------
Echange de 3000+ liens PR 3 -> 5, me pm urgent !
Reply

Marsh Posté le 04-04-2008 à 15:53:33    

Hmm, pour la page de rendu, si j'ai bien compris, je dois créer une classe de view pour chaque zone de rendu?
genre HeaderView, ContentView, MenuView? qui prennent en entrée respectivement un objet header, un objet content et un objet menu?
 
Par contre, je ne comprends mais alors pas du tout ce que tu entends par "dans ton controller, il faut definir ta vue comme une composite de view". Un composite? C'est quoi? C'est une classe spéciale? Concrêtement, je vois pas ce que c'est...
Un chtit ex? Désolé, c'est justement la conversion théorie pratique qui me pose problème.
 
Quand tu parles de helpers, qu'est ce que ca implique? je les mets a part? si oui comment? comment sont ils passés à la view?
 
Grosso modo:
j'instancie une $new_page= new Page($title)
je rajoute des trucs dedans
puis je fais un  
$page_handler = new PageView();
$page_handler->display($new_page)
mais alors il faut des tas de méthodes pour rajouter des liens, des images etc a ma page?
 
Pour addressbook je ne comprends pas. addressbook ne contient aucun contact, ca contient les infos de conf de mon application, et ca fait tous les acces a la base de données, qui est un champ d'addressbook en fait.
si je dois pas faire les acces a la bdd la dedans, ou dois je les faire?
 
Encore merci, et désolé si j'écris un charabia pas possible, mais c'est vraiment pas clair dans ma tête.

Reply

Marsh Posté le 07-04-2008 à 09:44:50    

Un composite c'est un objet qui en contient d'autres : http://www.php.net/~helly/php/ext/spl/

 
Code :
  1. class Controller {
  2. //Controller::view (access public)
  3. public function run()
  4. {
  5. $this->_init_env();
  6. $this->view->add('menu', MVC::factory('view', (array)$params))
  7. $this->view->add('header', MVC::factory('view', (array)$params))
  8. $this->view->add('content', MVC::factory('view', (array)$params))
  9. $this->view->render();
  10. }
  11. }
  12. Class View extends MVCobject {
  13. //class Filter
  14. //les filtres
  15. protected $_preFilters;
  16. protected $_postFilters;
  17. //les donnee. Type MVCObject implemente ValueObject
  18. public $data;
  19. public function __contruct($params = arrray())
  20. {
  21. $this->_setUp($params);
  22. }
  23. public function render()
  24. {
  25.   foreach($this->data as $view_objects) {
  26.     $view_objects->render();
  27. }
  28. }
  29. }
 


Pour addressBook, dans son etat final il doit contenir plusieurs Contact non ?

 

Si oui, alors ces contact viennent d'objet DAO specialise dans la communication avec la DB. Plusieurs facons de faire ces objets.

 

Soit ton modele implemente une interface qui lui permet de communiquer avec ces DAO. Soit ces DAO te retourne tes objets du modele (retourne Contact ou AdressBook qui est un aggregat de Contact)

 


Edit: Pour les methodes helpers de la view. Tu ferais mieux de t'en passer car PHP est un langage lent. Il serait plus judicieux de faire le code HTML normalement (pas de fonctions pour generer du html).


Message édité par supermofo le 08-04-2008 à 10:38:39

---------------
Echange de 3000+ liens PR 3 -> 5, me pm urgent !
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed