Page 1 sur 1

La POO et les requêtes

Posté : 22 sept. 2011, 22:22
par Skw33d
Salut tous le monde,

Voilà maintenant quelques mois que j'ai commencé la POO, et l'utilisant jusqu’à maintenant de façon simple pour essayer de bien comprendre sans pour l'instant m'occuper de l'optimisation, je me pose depuis quelques temps tout de même quelques questions sur lesquels j'aimerais bien avoir vos réponses et vos techniques. Tout ça dans une optique d'optimisation et bien sûr de meilleur compréhension.

J'ai par exemple une application Calendrier. Composé de différentes classes : User, Event, Category, Group...
Chaque classe qui représente ici un objet à son gestionnaire implémentant toutes les requêtes vers la DB.
J'ai avec une base de données relationnelles et chacun des objets cités à une table qui lui correspond.
Pour expliquer ma question, je vais vous donner un exemple lors de l'affichage d'un Event.

Tout d'abord, voici un DESC de ma table Event :
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| title       | varchar(30)      | NO   |     | NULL    |                |
| description | text             | NO   |     | NULL    |                |
| date_start  | date             | NO   |     | NULL    |                |
| time_start  | time             | YES  |     | NULL    |                |
| date_end    | date             | NO   |     | NULL    |                |
| time_end    | time             | YES  |     | NULL    |                |
| adress      | varchar(255)     | YES  |     | NULL    |                |
| phone       | varchar(30)      | YES  |     | NULL    |                |
| category    | int(5) unsigned  | NO   | MUL | NULL    |                |
| user        | int(5) unsigned  | NO   | MUL | NULL    |                |
| visible     | tinyint(1)       | NO   |     | 1       |                |
+-------------+------------------+------+-----+---------+----------------+
category, group, user représente simplement les ID des objets dans leur table respective.
Donc quand j'affiche un Event, j'appelle la méthode de son gestionnaire : $manager->getEvent($id) par exemple qui va chercher les données et qui me retournera un objet Event avec ses données hydratées.

Mais lorsque j'affiche les données, j'ai dans mon objet hydraté uniquement les ID des objets.
Alors affiché le nom de la catégorie avec l'ID 17, je serai donc obliger d'instancier le gestionnaire de Category et de faire $categoryManager->get(17); pour obtenir les informations sur ma catégorie.
Ça me fait donc une requête en plus. Et puis pareil pour afficher l'auteur (ici user), je dois faire la même chose.

Je connais les jointures, et je sais les utilisés. Mais est ce que ça ne serait pas "non conforme au concept de la POO" de ne pas tout traiter comme un objet ?
Pour l'instant dans mon objet Event : j'ai les méthodes setTitle, setId... Celles ci ne font que définir un attribut.
Si j'utilise une jointure : ma méthode setCategory deviendrait alors quelque chose comme :
public function setCategory( $id )
{
    $categoryManager = new CategoryManager($this->db);
    $this->category = $categoryManager->get($id);
}
Mon objet se mettrait alors à contenir plein d'autre méthodes et appellerait plusieurs gestionnaires. Qu'en pensez vous ? Est ce la bonne solution ? Ou celle que j'utilise actuellement est la bonne.

Il y aussi une autre question qui me turlupine : est qu'un gestionnaire d'un objet à le droit de retourner d'autre objet. Je veux dire par droit, est ce une bonne façon de faire ?

Par exemple, si je veux récuperer tous les Event d'une Category. Faut il implémenter dans le CategoryManager une méthode getEvents(Category $category) qui ferait donc une requête sur la table Events et récupérerait les Event ou l'ID de la Category est égale à la sienne.
Ou, est il mieux d'implémenter la méthode dans EventManager avec une méthode getEventsCategory(Category $category) qui ferait la même requête.
Pour ma part je pense la deuxième solution étant celle convenable. Mais sachant que Category et Event sont deux objets "dépendant" (un Event doit avoir une Category) cela doit reste correct ?


Merci à ceux qui me liront et encore plus à ceux qui me répondront. :D J'espere que vous comprenez ce que je demande, j'ai fait au mieux pour être le plus clair possible ;)

Re: La POO et les requêtes

Posté : 23 sept. 2011, 01:33
par AB
Je n'ai pas le temps de rentrer dans le détail de toutes tes questions mais d'une manière générale, on modélise une base de données et les requêtes avec ou sans jointure que l'on doit faire, indépendamment de l'utilisation ou non de la poo. C'est l'optimisation des requêtes pour avoir un minimum de temps de réponse et de charge du serveur du serveur sql qui importe le plus et non pas le type de code que tu utilise.

Re: La POO et les requêtes

Posté : 23 sept. 2011, 09:31
par Yosh
Ayant développer mon propre framework, je me suis poser la même question.

J'ai opté pour l'hydratation d'objets à partir d'une seul requête.

Par exemple dans ton cas, la définition de la class Event contiendrait un objet de type User, un autre de type Category. Et lorsque je fait ma requête de sélection, je viens directement hydrater les sous objet de la class Event.

Re: La POO et les requêtes

Posté : 28 sept. 2011, 22:39
par Skw33d
D'accord, je vous remercie de vos réponses ;)

On retrouve tout de même (bien que pas super gênant) une certaine redondance du code au niveau des requêtes.
Si on a des jointures sur plusieurs tables différentes... et qu'on a par exemple 3 méthodes qui vont nous retourner des Category par exemple... dans ces 3 méthodes on devrait retaper les mêmes jointures pour nos requêtes..
Bien que le copié / collé existe, est ce bien propre de faire ainsi ? Faudrait il mieux par exemple stocké ses jointures dans des variables que l'on vient concaténer avec notre requête au cas ou l'on devrait par exemple modifier un champ ou le nom d'une table (ce qui nous éviterait d'aller modifier à chaque endroit pour une modification).

Ou bien, jugez vous que dans la conception d'une application, une fois la base de données modéliser, il n'y a plus aucune raison d'y toucher et donc du SQL redondant n'est pas très gênant. Votre avis ? Comment à votre manière procéder vous ? J'espère que je ne dérive pas trop du sujet en m'écartant dans la rubrique Méthodologie.

Merci à vous.

Re: La POO et les requêtes

Posté : 29 sept. 2011, 09:59
par nhachet
Si vraiment tu as des portions de codes SQL que tu veux réutiliser lors de la création de tes requêtes, tu peux les placer en constantes de classe ou en méthodes publiques dans ta couche DAO.

Du coup, on se retrouve avec les "couches" suivantes (par ordre d'appel) :

1. Contrôleurs
2. Services
3. DAL
3.1 DAO
3.2 Entités

Re: La POO et les requêtes

Posté : 02 oct. 2011, 22:25
par Skw33d
Ok. Je te remercie de tes conseils Nhachet.

Après avoir lu ceci qui correspond assez à mon cas au niveau des requêtes :
php-oriente-objet/cas-pratique-blog-poo-t247335.html

Je me demande maintenant quel est le plus intéressant au niveau de la requête d'un point de vue performances.
Dans le cas d'une relation 1 - N, on a le choix , comme le dit bien naholyr :
1. Faire une seule requête de N lignes : N fois le même billet, et 1 fois chaque commentaire. On prend les infos du billet de la première ligne pour le construire, puis on construit chaque commentaire. Total : 1 seule requête de N * (X+Y) champs.

2. Faire deux requêtes : 1 pour le billet, 1 pour les N commentaires. Total : 1 requête de X champs, et 1 de N*Y champs.


Mais il dit aussi qu'en terme de performances cela peut jouer. Dans vos développements qu'avez vous jugé le plus performants entre les deux méthodes ? Qu'avez vous trouvé aussi le plus pratique ? Pour ma part je ne trouve pas 1ère solution la plus pratique. Peut être est elle la plus performante. Je trouve que les deux ne vont souvent pas bien ensemble. Qu'en pensez vous ?

Merci d'avance.

Re: La POO et les requêtes

Posté : 03 oct. 2011, 09:59
par nhachet
Si tu as des contraintes de performances, je te conseille d'utiliser la seconde solution (2 requêtes).
Dans le cas contraire, dès que la volumétrie de ta base va commencer à être significative, tu vas harceler ton SGBD de requêtes.

Dans ce cas, mieux vaut une requête avec plusieurs jointures et des index bien placés.