POO début...

Rechercher

POO début...

Par saturn1  -  9 reponses  -  Le 27/11/2008 18:21  -  Editer  - 

Bonjour j'ai lu le, assez bon tutorial sur la POO et j'ai moi même créer un espace membre simpliste en Orienté objet.

Mais après avoir fait ce code je n'ai pas vu de gros avantage par rapport au procédural. De plus je voulais savoir si par exemple je fais un site avec 10 modules si je dois essayer de faire des classes communes à ces 10 modules pour essayer de réutiliser le code ?

Merci à vous.

En gros ma question c'est comment utiliser la poo pour un site assez gros avec plusieurs modules et comment réutiliser du code.

 

Réponses apportées à cette discussion

Par Emacs  -  Le 27/11/2008 21:22  -  Haut de page  - 

Bonjour Saturn1,

Tout d'abord je serai curieux de découvrir une partie de ton code d'espace membre pour vérifier s'il a bien été conçu ou pas. En effet, la POO prend plus de temps à écrire au début que du code procédural mais s'avère par la suite plus facile et rapide à utiliser.

Pour répondre à ta question sur la réutilisabilité du code, c'est là tout l'art de maîtriser l'orienté objet. Ca vient avec l'expérience. Lorsque tu développes tes propres classes, il faut arriver à les développer de telle sorte à ce qu'elles soient les plus génériques possibles pour pouvoir ensuite être réutilisées facilement dans différents projets. Si les projets demandent ensuite de spécialiser davantage tes classes alors tu pourras faire jouer très facilement les avantages de l'héritage de classes.

Prenons un exemple simple. Pour mon site A, j'ai besoin de pouvoir gérer la session de mon utilisateur grâce aux sessions natives de PHP tandis que pour mon site B j'aurais besoin de gérer les sessions en base de données. Si l'on y réfléchit bien, une session est un objet qui a un identifiant, une durée de vie et qui contient des données (sérialisées ou pas, on s'en fiche).

De ce fait, on peut donc déjà imaginé une classe abstraite, une interface ou bien une classe concrète qui définit les propriétés et méthodes de base d'un objet session. Ici je choisis de créer une classe abstraite Session qui définit les attributs et méthodes que l'on devra obligatoirement redéfinir dans des classes filles.

<?php
abstract class Session
{
  protected $session_id = null;
  protected $session_data = null;
  protected $session_lifetime = 3600; // 3600 secondes = 1 heure
  abstract public function read();
  abstract public function write($data);
  public function getSessionId()
  {
    return $this->session_id;
  }
  // etc...
}

Nous avons ici deux méthodes abstraites read() et write(). Cela veut dire que l'on sera obligé de les redéfinir dans une classe fille. Par déduction, nous allons créer deux classes. L'une pour gérer les sessions PHP et l'autre pour gérer des sessions en BDD. Et dans chacune d'elles on va redéfinir les deux méthodes pour gérer la lecture et l'écriture de la session.

<?php
class NativePhpSession extends Session
{
  public function read()
  {
    return $_SESSION['variable'];
  }
  public function write($data)
  {
    $_SESSION['variable'] = $data;
  }
}
class DatabaseSession extends Session
{
  public function read()
  {
    // On considère que l'on a un objet pour faciliter l'appel à la base de données
    return $this->db->query('SELECT * FROM session WHERE session_id = ?', array($this->session_id))->fetchOne();
  }
  public function write($data)
  {
    if ($this->sessionExists())
    {
      $this->db->query('UPDATE session SET data = ?, max_lifetime = ? WHERE session_id = ?', array($data, $this->refreshSessionLifeTime(), $this->session_id));
    }
    else
    {
      $this->db->query('INSERT INTO session (session_id, max_lifetime, data) VALUES(?,?,?)', array($this->generateSessionId(), $this->refreshSessionLifeTime(), $data));
    }
  }
  // autres méthodes : refreshSessionLifeTime(), sessionExists(), generateSessionId()...
}

Et voilà, rien qu'en faisant ça, nous avons réalisé (grosso modo bien sûr) deux composants qui gère une session utilisateur différemment. Le premier avec les sessions natives et le second avec une base de données. Mais au final, quel que soit le site que tu développeras et la manière dont seront gérées les sessions, tu utiliseras les méthodes de la classe Session. Ca veut dire que sur ton site A et ton site B, il te suffira respectivement de faire :

<?php
// Dans chaque fichier de config de tes sites
// Site A : session native PHP
$session = new NativePhpSession();
$data = $session->read();
$session->write('mes data');
// Site B : session en base de données
$session = new DatabaseSession();
$data = $session->read();
$session->write('mes data');

Si un jour tu veux que ton site B utilise les sessions natives de PHP plutôt que la BDD alors il te suffira de changer uniquement la ligne new DatabaseSession() en new NativePhpSession(). Tout le reste du code reste inchangé.

Voilà donc rapidement comment on arrive à faire du code réutilisable (mes deux classes sont prêtes à être utilisées pour mes prochains projets) et facilement maintenable.

++

Hugo.

 
Par saturn1  -  Le 27/11/2008 21:50  -  Haut de page  - 

Merci de ta réponse.

Voici mon code de mon espace membre c'est vraiment minable :

 

<?php
class membre {
  public $pseudo;
  public $pass;
  public function __construct() { }
  public function connexion() {
    if($this->pseudo=='greg' && $this->pass='greg') {
      echo 'Connecté.';
    }
    else {
      echo 'Non Connecté.';
    }
  }
}
?>

et

<?php
include("class/identification_membre.php");
$membre1 = new membre();
$membre1->pseudo = mysql_real_escape_string($_POST['pseudo']);
$membre1->pass = mysql_real_escape_string($_POST['pass']);
$membre1->connexion();
?>

J'ai à peu près compris ton code ;).

Mais moi ce n'est pas temps réutiliser le code pour différent projet.

Mais réutiliser le code pour des modules différents pour des modules différents du même site.

Par exemple sur mon site j'ai un module Article et news . (on remarque que c'est similairement la même chose)

Ne peut on pas créér une classe ArticleEtNews et gérer ces deux modules avec la même classe?

Par exemple : (je fais sa rapidement désolé pour les fautes :)

<?php
class ArticleEtNews {
protected $table;
protected $nomModule;
public function modifier() {
$query = mysql_query("update '".this->table."' SET ...");
}
}

Enfin la c'est un exemple car il faut gérer les noms des différents champs dans la table tout sa..

 

Ou alors tu me conseilles clairement d'utiliser : UN MODULE = UNE CLASSE

 

MERCI BEAUCOUP !!

 

Merci

 
Par Emacs  -  Le 27/11/2008 22:34  -  Haut de page  - 

Effectivement ton code est mauvais et inutilisable en l'état. Pour commencer, on ne fait pas d'attributs publics car cela incite le développeur à les accéder directement comme tu le fais. Ce n'est pas du tout une bonne pratique.

D'autre part, une classe juste pour ça ne sert à rien. Il n'y a aucun intérêt à spécifier en dur les identifiants justes à l'intérieur même de la classe. Une classe Membre est pratique lorsque tu dois représenter une ligne d'une table "membre" de ta base de données par exemple.

Concernant ta question, tu peux faire une classe parente "PlugIn" ou "Module" qui contient les informations générales d'un module (son nom, son auteur, sa version...). Chaque module que tu code doit dériver cette classe. Ainsi tu auras quelque chose comme :

<?php
class Module
{
}
class ModuleNews exends Module
{
  private $news = array();
  public function add(News $news)
  {
    $this->news[] = $news
  }
}
class ModuleArticle extends Module
{
}
class News
{
  public function save()
  {
    // Ajout ou edition de la news en Bdd
  }
  public function delete()
  {
    // Suppression de la news de la bdd
  }
}
class Article
{
  public function save()
  {
    // Ajout ou edition de l'article en Bdd
  }
  public function delete()
  {
    // Suppression de l'article de la bdd
  }
}

++

 
Par jptre8  -  Le 28/11/2008 04:08  -  Haut de page  - 

J'aurait une question a te poser sa peu parraître stupide mais bon je suis nouveau d'hier dans l'objet en php (Alors j'ai encore des problemes de logiques).

Au fond est-ce que chaque class que tu a crée ci-haut est en fait un objet qui en inclut un autre ???

ex:obj module dans lequel on place les objet Module arcticle et module news qui a leurs tour vont contenir des objet news et Article ???

 

 

 

 
Par saturn1  -  Le 28/11/2008 10:11  -  Haut de page  - 

jptre8 > C'est mon topic dégage ^^ nan jdéconne mais je voudrais pas te répondre de bêtises...

Emacs > Sinon je souhaite réaliser un espace membre complet pour mon futur site.

Pour les attributs publics je vais les mettre en private et utiliser des setters et des getters ou (__set et __get).

Mais sinon quand tu me dis :

D'autre part, une classe juste pour ça ne sert à rien. Il n'y a aucun intérêt à spécifier en dur les identifiants justes à l'intérieur même de la classe. Une classe Membre est pratique lorsque tu dois représenter une ligne d'une table "membre" de ta base de données par exemple.

Je ne vois pas trop ce que je dois faire concrétement.

Merci de prendre de ton temps.

 

 

 
Par Emacs  -  Le 28/11/2008 13:20  -  Haut de page  - 

Au fond est-ce que chaque class que tu a crée ci-haut est en fait un objet qui en inclut un autre ???

Non pas forcément. Dans les exemples que j'ai présenté plus haut, je ne fais que dériver (ou dit autrement étendre, spécialiser) des classes génériques pour les rendres plus complètes en fonction des besoins nécessaires de l'application (sessions natives ou bien session en BDD).

ex:obj module dans lequel on place les objet Module arcticle et module news qui a leurs tour vont contenir des objet news et Article ???

Non dans mon exemple, un objet NewsModule ne fait qu'étendre les spécificités de la classe générique Module. On dit que l'objet NewsModule hérite des propriétés et méthodes de la classe qu'elle dérive (Module).

Par contre on pourrait très bien imaginer une classe NewsCollection qui contiendrait un certain nombre de d'objets News. Ce qui donne par exemple :

<?php
abstract class BaseCollection
{
  protected $collection = array();
  public function add(Object $obj)
  {
    $this->collection[] = $obj;
  }
  public function getAll()
  {
    return $this->collection;
  }
  public function count()
  {
    return count($this->collection);
  }
}
class NewsCollection extends BaseCollection
{
  // Ici des méthodes pour traiter ta collection d'objets News
}
// On crée une collection de news
$newsCollection = new NewsCollection();
// On crée des news
$news1 = new News();
$news1->setTitle('Ma news 1');
$news2 = new News();
$news2->setTitle('Ma news 2');
$news3 = new News();
$news3->setTitle('Ma news 3');
// On lui ajoute des news
$newsCollection->add($news1);
$newsCollection->add($news2);
$newsCollection->add($news3);
// On récupère les news dans une boucle foreach()
foreach($newsCollection->getAll() as $news)
{
  echo $news->getTitle(),'<br/>';
}

Là encore je pourrais améliorer le comportement de ma newsCollection dans la boucle foreach() en lui faisant implémenter un itérateur. Mais ça c'est déjà du developpement avancé en POO.

Je ne vois pas trop ce que je dois faire concrétement.

Si tu as une table "membre" alors tu peux créer une classe "Membre" dans laquelle tu auras pour chaque champ de ta table un attribut privé que tu pourras setter et getter. Donc si j'ai une table membre avec les champs id, login, pwd, email alors dans ma classe Membre j'aurais 4 attributs privés $id, $login, $pwd, $email et leurs getter / setter associés. Tu ajoutes des méthodes save() et delete() qui permettront de gérer à la fois la création / édition des infos et la suppression en BDD.

++

 
Par saturn1  -  Le 28/11/2008 13:59  -  Haut de page  - 

Merci emacs,sa me parait claire .

Je vais maintenant passez au codage..

Je repasserais surement ici pour avoir de l'aide!!

MErci Beaucoup

 
Par Vini  -  Le 29/11/2008 11:11  -  Haut de page  - 

Salut à tous ! et merci Emacs !

je me posait à l'instant même une question sur le sur les collections d'objet !

Ce topic tombe à pic ^^

je connaissait en JAVA avec l'interface List , ArrayList... mais pas en php

aussi et peut etre je me trompe ca me fais penser hors mis l'histoire de l'espace membre à de une application CRUD( Create, Read, Update, Delete)

dans le principe biensur ! par rapport à la base de donnée mais limité

par rapport à la class module ou article...

Vini...

class Article
{
public function save()
{
// Ajout ou edition de l'article en Bdd
}
public function delete()
{
// Suppression de l'article de la bdd
}
}
 
Par jptre8  -  Le 29/11/2008 13:54  -  Haut de page  - 

Merci beaucoup emacs !

 

Ajouter une réponse à la discussion

Seuls les membres connectés sont autorisés à poster dans les forums !

Identifiez-vous
Join |  ID/MDP? |