03-08-2013, 04:50 PM
Dans la même classe, oui, ok, je fais confiance à mon code. La modification avec contrôle revient finalement à sortir un élément de la collection, puis en faire re-rentrer un comme n'importe quel autre élément à entrer.
Cela me semble différent de "faire sortir une référence au livre". C'est ça que je n'aime pas, et que Array.forEach() semble faire. Si mon callback stocke cette référence dans une variable globale, je pourrai faire ce que je veux avec l'objet référencé, et le conteneur n'arrivera pas à faire sa vérification interne...
Pour le code (jouons le jeu, faisons full propre comme je ferai un projet final)
Cela me semble différent de "faire sortir une référence au livre". C'est ça que je n'aime pas, et que Array.forEach() semble faire. Si mon callback stocke cette référence dans une variable globale, je pourrai faire ce que je veux avec l'objet référencé, et le conteneur n'arrivera pas à faire sa vérification interne...
Pour le code (jouons le jeu, faisons full propre comme je ferai un projet final)
Code PHP :
<?php
interface IMAJUSCULES
{
public /*void*/ function MAJUSCULES();
}
interface ILivreAjoutable
{
public function addLivre(/*Livre*/ $p_livre);
}
interface ILivreRetirable
{
public /*Livre*/ function getLivre(/*string*/ $p_titre);
}
interface IBibliotheque extends ILivreAjoutable, ILivreRetirable
{
}
interface ITitreRecuperable
{
public /*string*/ function getTitre();
}
interface ITexteRecuperable
{
public /*string*/ function getContenu();
}
interface ILivre extends ITitreRecuperable, ITexteRecuperable
{
}
/*objet*/
class Livre implements ILivre
{
protected /*string*/ $titre;
protected /*string*/ $texte;
public function __construct(/*string*/ $p_titre, /*string*/ $p_texte)
{
$this->titre = $p_titre;
$this->texte = $p_texte;
}
public /*string*/ function getTitre()
{
return ($this->titre);
}
public /*string*/ function getContenu()
{
return ($this->texte);
}
}
/*objet*/
class Bibliotheque implements IBibliotheque
{
protected /*array[string]*/ $titres;
protected /*array[string]*/ $textes;
public function __construct()
{
$this->titres = array();
$this->textes = array();
}
public function addLivre(/*Livre*/ $p_livre)
{
$this->titres[] = $p_livre->getTitre();
$this->textes[] = $p_livre->getContenu();
}
public /*Livre*/ function getLivre(/*string*/ $p_titre)
{
$index = array_search($p_titre, $this->titres);
unset($this->titres[$index]);
unset($this->textes[$index]);
return (new Livre($this->titres[$index], $this->textes[$index]));
}
}
//-----------------------
class MonLivre extends Livre implements IMAJUSCULES
{
public /*void*/ function MAJUSCULES()
{
$this->titre = strtoupper($this->titre);
$this->texte = strtoupper($this->texte);
}
}
class MaBibliotheque extends Bibliotheque implements IMAJUSCULES
{
public /*void*/ function MAJUSCULES()
{
// Comme mes données sont totalement miennes, j'en fais ce que je veux
if (mt_rand(0, 100) > 50)
{
echo('I use array_map<br/>');
$this->titres = array_map("strtoupper", $this->titres);
$this->textes = array_map("strtoupper", $this->textes);
}
else
{
echo('I new MonLivre()<br/>');
$livres = array();
foreach ($this->titres as $key=>$titre)
{
$livre = new MonLivre($titre, $this->textes[$key]);
$livre->MAJUSCULES();
$livres[] = $livre;
}
$this->titres = array();
$this->textes = array();
foreach ($livres as $livre)
{
$this->titres[] = $livre->getTitre();
$this->textes[] = $livre->getContenu();
}
}
}
}
// Main
$myBook = new Livre('Lorem Ipsum', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit,...');
$bibliotheque = new MaBibliotheque();
$bibliotheque->addLivre($myBook);
$bibliotheque->MAJUSCULES(); // Bibliothèque, débrouilles-toi !
// $myBook est resté en minuscules !
// C'est le contenu de la Bibliothèque qui est passé en majuscules.
var_dump($bibliotheque);
?>
Single Responsability: MaBibliothèque a la responsabilité de gérer le paquet de Livres dans son ensemble.
Open/Close principle: Mes modifications ont été faites en aval (ok, mes attributs n'auraient pas du être "private" d'origine)
Liskov substitution principle: Ok
Interface segregation principle: Corrigé (c'est vrai que je n'utilise pas assez les interfaces)
Depency injection: C'est l'un de ceux avec lequel j'ai le plus de mal (et avec lequel je ne suis pas d'accord), puisque via cette dépendance, le développeur peut avoir une porte "d'entrée" dans la classe (avec new Bibliotheque($myConteneur = new Conteneur()) qui permet alors de traiter le conteneur de Bibliothèque à travers $myConteneur).