De la théorie à la pratique

Mammouth du PHP | 531 Messages

01 sept. 2008, 23:24

Bonsoir,
De la théorie à la pratique c'est jamais évident, alors j'ai besoin que l'on m'éclaircisse :
Dans cet exemple, j'ai un début d'objet page qui à 3 attributs et une table qui à autant de champs.
class page {
	public $id;
	public $nom;
	public $fichier;
	public function __construct( $id, $nom, $fichier )
	{
		$this->id = $id;
		$this->nom = $nom;
		$this->fichier = $fichier;
	}
}
Maintenant je veut obtenir la liste des pages, je fait donc :
$sql = "SELECT * FROM zen_pages";
$query = mysql_query($sql) or die( mysql_error() );
while( $page = mysql_fetch_array( $query ) )
{
	$page = new page( $page['id_pages'] , $page['nom'] , $page['fichier'] );
	echo $page->id;
}
Seulement en tapant ces dernières lignes, je me dit mince, l'obtention de la liste des pages ça ne devrait pas être une méthode de la classe page ? Cette requête et cette boucle ne devraient pas se trouver être une fonction que j'appellerais getListe() ?

Réponse, j'en sais rien, c'est justement ça ma question ;)

Merci d'avance.

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

02 sept. 2008, 23:31

Tu te fais une classe que tu nomme ListePages qui encapsule et gère une collection d'objet de type "page" (ta classe)

Voici un exemple :
class page { 
    public $id; 
    public $nom; 
    public $fichier; 
    public function __construct( $id, $nom, $fichier ) 
    { 
        $this->id = $id; 
        $this->nom = $nom; 
        $this->fichier = $fichier; 
    } 
} 

class CollectionPages {
    private $liste;
    public function __construct(){
        $sql = "SELECT * FROM zen_pages"; 
        $query = mysql_query($sql) or die( mysql_error() ); 
        while( $page = mysql_fetch_array( $query ) ) 
        { 
            $page = new page( $page['id_pages'] , $page['nom'] , $page['fichier'] ); 
            $this->liste[] = $page;
        }
    }
    public function set ($liste){
       $this->liste = $liste;
    }
    public function get(){
        return $this->liste;
    }
    // ... etc... d'autres méthodes peuvent être implémentées comme : 
    // add, remove, exists, next, previous, first, last, eof, bof, count, clear, ...
}
Remarque que si tu fais dans ton programme principal exécutable ::
$listePages = new CollectionPages();
Avec ça Tu auras déjà récupéré toutes les pages de la base de données dans ta liste et il suffit de la parcourir pour en extraire les objets "page" qui y sont stockés :
foreach ($listePages->get() as $page){
    echo $page->id;
}
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Eléphanteau du PHP | 36 Messages

03 sept. 2008, 11:15

Ou sinon, tu peux utiliser le composant du Zend Framework appelé Zend_Paginator, avec un objet Zend_Db_Select, tout est déja construit.

J'écris d'ailleurs un mini-tuto sur PHPteam.net en ce moment, à ce sujet :wink:

http://www.phpteam.net/index.php/articl ... -framework
Julien Pauli - Formateur pôle PHP ZendFramework chez Anaska
Contributeur au projet Zend Framework
Ma page de tutoriaux, mon blog

Mammouth du PHP | 531 Messages

05 nov. 2008, 15:16

Je fait remonter le topic avec une petite question à propos de ces 2 classes :
<?php
class user { 
    public $id; 
    public $nom; 
    public function __construct( $id, $nom )
    { 
        $this->id = $id;
        $this->nom = $nom;
    }
	public function testerSiExiste()
	{
		$req = "SELECT id_poo_user FROM poo_user WHERE nom = '".$this->nom."'";
		$res = mysql_query( $req );
		if( mysql_num_rows( $res ) != 0 )
		{
			return true;
		}
	}
	public function add()
	{
		if( !$this->testerSiExiste() )
		{
			$req = "INSERT INTO poo_user ( id_poo_user, nom ) VALUES ( '', '".$this->nom."' )";
			$res = mysql_query( $req );
		}
	}
} 
class listeUser
{
    private $liste;
    public function __construct()
	{
        $req = "SELECT * FROM poo_user";
        $res = mysql_query( $req ) or die( mysql_error() );
        while( $user = mysql_fetch_array( $res ) ) 
        { 
            $user = new user( $user['id_poo_user'] , $user['nom'] );
            $this->liste[] = $user;
        }
    }
    public function get()
	{
        return $this->liste;
    }
}
// Liste
$listeUser = new listeUser();
foreach ( $listeUser->get() as $user )
{
    echo $user->nom;
}
// Ajout
$user = new user( NULL,'tutu' );
$user->add();
?>
Ma question est la suivante. La classe ListeUser ne devrait-elle pas être une méthode de la classe user ?

Je dirais que non car un groupe de personnes est différent d'une personne.
Mais en même temps je dirais que dans ce cas il n'y a qu'un seul groupe de personnes, donc faut-il vraiment le considérer comme un objet ? :?

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

06 nov. 2008, 00:33

Les classes de type liste d'objets sont des collections et représentent généralement, en principe, les occurrences (enregistrements) d'instances d'objets de même classe. Il n'est donc pas logique d'inclure une collection d'objets en tant que résultat de méthode d'une classe ayant la même nature. Car ce phénomène engendre en fait, une récursivité de définition qui n'est pas utilisable et donc consomme de l'espace objet pour rien.

Le plus juste est de séparer l'objet porté par la collection et l'objet collection lui même. Car l'objet porté est issu d'une classe métier et est porteur de données et la collection est simplement un support (liste) porteur. La relation entre une classe collection est une classe de données est de type 1..N/1..N, Ainsi on peut créer autant de collections (sélections) portant des objets de données que possible. Et vis-versa : un même objet de données peut se voir affecté à plusieurs collections existantes.

Par exemple, Les objets suivants sont des collections d'objets:

Code : Tout sélectionner

liste_produits_stock = array(objet_prod1, objet_prod2, objet_prod3) panier_de_Dupont::liste_produits_achetes = array(objet_prod1, objet_prod2) panier_de_Toto::liste_produits_achetes = array(objet_prod1, objet_prod3)
La différence entre les collections "liste_produits_stock" et "liste_produits_achetes" est que la première est une collection indépendante qui est créée pour contenir la liste des produits en stock, elle n'est pas intégrée dans l'objet produit puisque c'est elle qui l'intègre comme contenu.
Par contre la seconde collection est par définition intégrée dans l'objet "panier" et qui représente la liste des produits achetés. Sa présence en tant que membre d'un objet s'explique conceptuellement par la présence d'une association entre le panier et les produits qui est l'action d'achat.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 531 Messages

06 nov. 2008, 10:30

He ben merci pour les explications. Je comprend mieux.
C'est tellement abstrait l'objet que c'est difficile de ne pas faire n'importe quoi...

J'ai même un doute si par exemple je voulais vérifier la structure des nom, exemple ne pas autoriser les caractères spéciaux, si je devait incorporer cette vérification à l'objet ou si ça devait rester une fonction à part.

Pareil pour la méthode que j'ai ajouté, testerSiExiste. J'ai un doute, je me dit que ça pourrais plutôt faire partie d'une classe générique mysql ?

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

07 nov. 2008, 01:14

Alors, pour mieux clarifier les choses, je dirai que tout ce qui concerne un individu (une entité ou une classe) doit être attaché à cet individu comme ses propriétés et méthodes qui définissent ses caractéristiques et ses comportements.

Le cas de la validation du contenu d'une propriété comme le nom d'un client par exemple, relève du comportement de la classe et doit être intégré comme méthode de la classe.

Par contre le cas de la vérification de l'existence d'une occurrence relève du comportement d'une collection. Qui est mieux placé qu'une classe collection d'objets pour vérifier si une occurrence d'un objet existe ou pas dans la collection.

Par exemple, pour le premier car de validation de contenu, on peut parler d'une méthode Setter qui valide l'entrée de données dans les propriétés de la classe. Cela s'écrirait dans le cas d'une classe membre par exemple:
class Membre {
   // Propriétés
   private $pseudo;
   private $motDePasse;
   public  $validated = null; // sert à cumuler les états de validation des champs 

  // Méthodes Setter
  public function setPseudo($value){
        // Règle de validation n°1: obligatoire + caractères autorisés = a-Z/0-9 + >= 8 caractères
        if (trim($value)!=""  && !preg_match("#[^a-zA-Z0-9]#", $value)    && strlen($value)>=8) {
                $this->pseudo = $value;
                $this->validated!=null ? $this->validated &= true : $this->validated = true; // Cumul de true dans validated utilisant l'opérateur & (ET), sauf pour la première fois (validated=null)
        }
       else $this->validated = false; // Erreur de la règle n°1
        //
       return $this->validated; 
  }
  public function setMotDePasse($value){
        // Règle de validation n°2: obligatoire + >= 8 caractères
        if (trim($value)!=""  && strlen($value)>=8) {
                $this->motDePasse = $value;
                $this->validated!=null ? $this->validated &= true : $this->validated = true; // Cumul de true dans validated utilisant l'opérateur & (ET), sauf pour la première fois (validated=null)
        }
       else $this->validated = false; // Erreur de la règle n°2
        //
       return $this->validated; 
 }
 // Méthodes Getter
 public function getPseudo() { return $this->pseudo; }
 public function getMotDePasse() { return $this->motDePasse; }
} // fin classe
Et pour le second cas de la vérification de l'existence d'une occurence d'objet dans un tas :
class CollectionDeMembres {
    // Propriétés
    public $contenu = array();
    private $deleted = array(); // corbeille

    // Méthode d'ajout d'un membre (indexé par clé primaire=pseudo)
    public function add($membre) {
          if (! $this->exists($membre->getPseudo())) {
                   if ( $membre->validated == true){
                           $this->contenu[$membre->getPseudo()] = $membre; // Ajout du membre validé
                           return true;
                  }
         }
         return false;
    }
    
   // Méthode de recherche de l'existence d'un membre (accès par clé primaire=pseudo)
   public function exists($pseudoMembre) {
        if (isset($this->contenu[$pseudoMembre])) return true; // Recherche dans la collection, ...
        else 
        if ($this->getMembreFromDB($pseudoMembre))  return true; // ... puis dans la BD
        else return false;
   }
  
  // Méthode de mise à jour d'un membre existant (accès par clé primaire non modifiable = pseudo)
     public function update($membre) {
          if ($this->exists($membre->getPseudo())) {
                 if ( $membre->validated == true){
                       $this->contenu[$membre->getPseudo()] = $membre; // Remplacement du membre dans le même emplacement (clé=pseudo)
                       return true;
                 }
          }
          return false;
    }

  // Méthode de suppression d'un membre existant (accès par clé primaire)
     public function delete($pseudoMembre) {
          if ($this->exists($pseudoMembre)) {
                   $this->deleted[$pseudoMembre] = $this->contenu[$pseudoMembre]; // Mise en corbeille
                   unset($this->contenu[$pseudoMembre]); // Suppression de la liste officielle
                   return true;
          }
          else return false;
    }
  // Méthode de récupération des membres supprimés (se trouvant dans la corbeille)
     public function unDelete($pseudoMembre) {
         // récupérer Un membre désigné, si n'existe pas déjà
          if (! $this->exists($pseudoMembre)) {
                   $this->contenu[$pseudoMembre] = $this->deleted[$pseudoMembre]; // récup.
                   unset($this->deleted[$pseudoMembre]); // Suppression de la corbeille
                   return true;
          }
          else return false;
    }
     public function unDeleteAll() {
         // récupérer Tous les membres supprimés, si n'existent pas déjà
          foreach ($this->deleted as $membre) {
               $this->unDelete($membre->getPseudo()); // récup. un par un
          }
    }
   
  // Constructeur de la collection + remplissage à partir de la BDD
  function __construct($getFromDB=true) {
       if ($getFromDB == true) {
                // ... appel d'une fonction spéciale pour exécuter SQL : SELECT * FROM Membre
                // ... et remplir  la collection à partir de la table Membre
                $this->getAllFromDB();
       }
  }
  // DéConstructeur de la collection + mise à jour de la BDD
  function __destruct() {
                // ... appel d'une fonction spéciale pour exécuter SQL : Replace Into Membre
                // ... et mettre à jour la table Membre à partir de la collection
                $this->updateDB();
  }
 
  // Méthode de liaison avec la table Membre de la BDD 
  // Lire les membres à partir de la BD et remplir la collection
  public function getAllFromDB($clearCollection=true){
          if ($clearCollection == true) $this->contenu = array(); // Nouvelle collection ou non
          $sql = "Select pseudo, motDePasse From Membre";
          $result = mysql_db_query("test", $sql, mysql_connect("localhost", "root"));
          while ($result && $row=mysql_fetch_object($result)){
                 $membre = new Membre();
                 if ($membre->setPseudo($row->pseudo) && $membre->setMotDePasse($row->motDePasse) ) $this->add($membre);
          }
          mysql_close();
  }
  // Lire un membre à partir de la BD et l'affecter dans la collection (sert aussi comme recherche)
  public function getMembreFromDB($pseudoMembre){
          $sql = sprintf("Select pseudo, motDePasse From Membe Where pseudo='%s'", $pseudoMembre);
          $result = mysql_db_query("test", $sql, mysql_connect("localhost", "root"));
          if ($result && $row=mysql_fetch_object($result)){
                 $membre = new Membre();
                 if ($membre->setPseudo($row->pseudo) && $membre->setMotDePasse($row->motDePasse) ) return $this->add($membre); // Ajoute le membre dans la collection
          }
          else return false;
          mysql_close();
  }
  // Mise à jour de la BD à partir de la collection (Ajoute les nouveaux, modifie les anciens et supprime ceux qui sont dans la corbeille)
  public function updateDB() {
         // On commence par Supprimer les membres mis en corbeille
          mysql_connect("localhost", "root");
          foreach($this->deleted as $membre){
                 // Sauvegarde dans la table des membres supprimés avant suppression effective
                 $sql = sprintf("Replace Into MembreDeleted (date, pseudo, motDePasse) Values ('%s', '%s', '%s')", date("Y-m-d"), $membre->getPseudo(), $membre->getMotDePasse());
                 $result = mysql_db_query("test", $sql);
                 // Suppression effective
                 $sql = sprintf("Delete From Membre Where pseudo='%s'", $membre->getPseudo());
                 $result = mysql_db_query("test", $sql);
        }

          // Update et Insert = Replace
          foreach($this->contenu as $membre){
                  $sql = sprintf("Replace Into Membre (pseudo, motDePasse) Values ('%s', '%s')", $membre->getPseudo(), $membre->getMotDePasse());
                 $result = mysql_db_query("test", $sql);
          }
        mysql_close(); 
       // Vidage de la corbeille
       $this->deleted = array();   
  }
} // fin classe

Cas d'utilisation:

Validation de saisie d'un formulaire d'inscription de nouveau membre:
$listeMembres = new CollectionDeMembres(); // avec remplissage auto de la BD
$membre = new Membre();
//
if (! $membre->setPseudo($_GET['pseudo'])) $msg = "Le Pseudo est Obligatoire, doit être >= 8 caractères et ne doit contenir que les alphabets et les numériques";
else
if (! $membre->setMotDePasse($_GET['motDePasse'])) $msg = "Le Mot de passe est Obligatoire et  doit être >= 8 caractères";
else 
// Ajout 
if ($listeMembres->add($membre)) $msg = "Bienvenue, vous êtes enregistré";
else $msg = "Désolé, Le pseudo est déjà utilisé";

// Réponse
echo $msg;
Modifié en dernier par sadeq le 07 nov. 2008, 18:09, modifié 1 fois.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 531 Messages

07 nov. 2008, 13:38

Alors là je te remercie 1000 fois pour cet exemple complet.
Je comprend beaucoup mieux l'idée, par contre il va ma falloir de la pratique si je devais recréer une tel classe. Donc pour l'instant je l'étudie pour essayer de comprendre.

J'ai eu du mal pour récupérer la liste des user, car en fait $collectionMembre est un tableau qui contient un objet contenu qui lui même contient un tableau contenant des objets
Quand même réussi :
foreach($collectionMembre->contenu as $k=>$membre)
{
	echo $membre->pseudo;

}

Mammouth du PHP | 531 Messages

04 févr. 2009, 21:09

Je reviens sur ce topic pour quelques précisions :

Il peut y avoir plusieurs façon de créer un objet, et du coup j'ai du mal à comprendre quel sont les paramètres à passer au constructeur.

Pour reprendre la classe membre, et continuer dans la voie des setter je pourrais avoir un constructeur minimaliste :
function __construct($id){
$this->id = $id;
}
Si je créer une instance de membre depuis une base de données, pas de problème. Si je crée un nouveau membre, il y a un soucis : En effet ce membre n'existant pas il n'a pas encore d'id.

Je suis donc obligé de faire :
$membre = new membre(null);
J'ai l'impression que ce n'est pas très propre.
Dans ce cas pourquoi ne pas faire un setter pour l'id aussi ? Un constructeur est t-il obligatoire ?

ViPHP
ViPHP | 4674 Messages

04 févr. 2009, 23:56

Hey :),

N'oublie pas que le constructeur peut avoir des valeurs par défaut (comme toutes les méthodes et fonctions en PHP).
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

05 févr. 2009, 00:38

En effet, sous PHP, pour qu'un constructeur supporte en même temps l'appel sans paramètres et avec paramètres (qui est l'équivalent à la notion de surcharge dans le modèle objet) il faut définir les paramètres optionnels avec des valeurs initiales. Par exemple:
Si le constructeur de la classe Membre est définit comme ça:
function __construct($id=null){
$this->id = $id;
}
Avec ça, on peut faire 2 types d'instanciations:
$m1 = new Membre(1); // un membre ayant l'id 1
$mx = new Membre(); // un membre sans id
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 531 Messages

05 févr. 2009, 01:19

Ah d accord merci, je savais bien que j'avais vu ça quelque part ;)
C'est pas évident tout ça, mais à force de pratiquer je découvre des réponses.
Je crois que j'ai déjà bien compris qu'il faut séparer l'objet lui même et les méthodes qui font la relation entre cet objet et la base de données. Je viens enfin de trouver l'utilité d'avoir des seter et des geter au lieu d'avoir un constructeur complet. Bon c'est pas encore gagné mais à force de me retrouver coincé avec des classes mal construites je comprends mieux.

Voilà ma toute dernière qui est vraiment très simple, elle sert juste dans le cadre d'un lexique. J'espère qu'elle est à peu près juste... ;) :
<?php
class definition{
	private $id;
	private $libelle;
	private $valeur;
	// setter
	public function __consctruct($id=null){
		$this->id = $id;
	}
	public function setLibelle($value){
		if($value == null){
			return false;
		}
		$this->libelle = $value;
		return true;
	}
	public function setValeur($value){
		if($value == null){
			return false;
		}
		$this->valeur = $value;
		return true;
	}
	// getter
	public function getLibelle(){
		return $this->libelle;
	}
	public function getValeur(){
		return $this->valeur;
	}
	public function getId(){
		return $this->id;
	}
}
?>

<?php
class gestionDefinition{
	public function constructUniq($id){
		$val = array(':id'=>$id);

		$req = "SELECT * FROM definition WHERE idDefinition = :id";

		$res = PDO2::getInstance()->prepare($req);

		$res->execute($val); 

		$row = $res->fetch(PDO2::FETCH_OBJ);
		$objet = new definition($row->idDefinition);
		$objet->setLibelle($row->libelle);
		$objet->setValeur($row->valeur);
		return $objet;
	}
	public function constructAll(){
		$collection = new collection();
		$req = "SELECT * FROM definition ORDER BY libelle ASC";

		$res = PDO2::getInstance()->prepare($req);

		$res->execute($val); 

		while($row = $res->fetch(PDO2::FETCH_OBJ)){
			$objet = new definition($row->idDefinition);
			$objet->setLibelle($row->libelle);
			$objet->setValeur($row->valeur);
			$collection->add($objet);
		}
		return $collection;
	}
}
?>

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

05 févr. 2009, 10:16

Très bien.

Tu as oublié un "setId()" dans le lot.

Voici une autre écriture:
<?php
class definition{
    private $id;
    private $libelle;
    private $valeur;

    // setter
    public function __construct($id=null, $libelle=null, $valeur=null){
        $this->setId($id);
        $this->setLibelle($libelle);
        $this->setValeur($valeur);
    }
    public function setId($value){
        if($value == null){
            return false;
        }
        $this->id= $value;
        return true;
    }
    public function setLibelle($value){
        if($value == null){
            return false;
        }
        $this->libelle = $value;
        return true;
    }
    public function setValeur($value){
        if($value == null){
            return false;
        }
        $this->valeur = $value;
        return true;
    }

    // getter
    public function getId(){
        return $this->id;
    }
    public function getLibelle(){
        return $this->libelle;
    }
    public function getValeur(){
        return $this->valeur;
    }
}
?>

<?php
class gestionDefinition{
    public function constructUniq($id){
        $val = array(':id'=>$id);

        $req = "SELECT * FROM definition WHERE idDefinition = :id";

        $res = PDO2::getInstance()->prepare($req);

        $res->execute($val); 

        $row = $res->fetch(PDO2::FETCH_OBJ);

        return  new definition($row->idDefinition, $row->libelle, $row->valeur);
    }
    public function constructAll(){
        $collection = new collection();

        $req = "SELECT * FROM definition ORDER BY libelle ASC";

        $res = PDO2::getInstance()->prepare($req);

        $res->execute($val); 

        while($row = $res->fetch(PDO2::FETCH_OBJ)){
            $objet = new definition($row->idDefinition, $row->libelle, $row->valeur);
            $collection->add($objet);
        }
        return $collection;
    }
}
?> 
Modifié en dernier par sadeq le 05 févr. 2009, 14:11, modifié 1 fois.
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 531 Messages

05 févr. 2009, 10:27

Ah je m'étais dit qu'il était inutile faire des setter sur l'id qui etait de toute façon initialisé par le constructeur.

Mais du coup je crois bien voir l'intérêt d'avoir un constructeur complet couplé à des setters :

- Pas besoin de vérifier les données qui viennent de la db, pas besoin de passer par les setters donc
- Possibilité de construire un objet n'utilisant pas tous les attributs de la classe

Par contre ça va à contre sens de la sécurité qu'apportent les setters non ?
Si l'on est plus obligé de passer par eux pour instancier un objet, on est donc plus obligé de vérifier les données... ?


Pour revenir aux classes de gestion, j'ai assez de mal. Par exemple si je devais placer une méthode "crypter valeur" ( totalement ionutile mais c'est pour l'exemple ), devrait-elle faire partie de la classe definition ou gestionDefinition ?

Merci encore pour les explications

ViPHP
ViPHP | 4674 Messages

05 févr. 2009, 13:47

Faire ou ne pas faire (telle est la question) un setter sur l'ID dépend de ton fonctionnement. Si tu veux que l'ID soit non-modifiable (soit constant ou en lecture-seule), alors tu as deux solutions : pas de setter, c'est le constructeur qui fait le travail, soit ton setter est protégé (ou privé, encore selon ce que tu veux faire, soit c'est en lecture-seule pour la classe ou sa famille, respectivement pour privé ou protégé).

Donc on ne peut pas dire que tu l'aies oublié, c'est juste que ça dépend de ta logique et de ton approche. Il ne faut pas faire un setter pour faire un setter, il faut le faire pour une raison précise, pour manipuler une donnée précise :).
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).