Précédent   Forum des professionnels en informatique > PHP > Langage > Syntaxe
Syntaxe Forum d'entraide sur la syntaxe de PHP et la POO. Avant de poster -> FAQ syntaxe, Cours d'initiation et cours de POO
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 16/02/2011, 09h22   #1
Expert Confirmé
 
Avatar de grunk
 
Homme Olivier
Développeur Web
Inscription : août 2003
Messages : 1 837
Détails du profil
Informations personnelles :
Nom : Homme Olivier
Âge : 27
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Industrie

Informations forums :
Inscription : août 2003
Messages : 1 837
Points : 3 318
Points : 3 318
Par défaut [POO] Petit problème de conception

Bonjour à tous,
je me confronte à un problème de conception , je ne sais pas vraiment comment m'organiser pour arriver à ce que je souhaite.
Je recode des classes pour la gestion d'image pour que je puisse facilement switcher de GD à un autre "driver".

J'ai donc une première classe Image_Image générique qui via une factory va appeller les bonne classe en fonction du driver choisi :
(les classes ont été simplifiée pour aller à l'essentiel)
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
<?php
class Image_Image
{
    private $path;
    private $extension;
    private $ressource;
    private $type; // 1:gif; 2:jpg; 3:png; 4:swf; 5:psd; 6:bmp; 7:tiff
    private $width;
    private $height;
 
    public function __construct($filename=null,$imageDriver = 'GD')
    {
        $this->ressource    =  Image_Abstract_Factory::getResource($imageDriver, $this);  
    }
 
    /**
     * Retourne la ressource selon le driver demandé
     * @return Image_Interfaces_Resource
     */
    public function getRessource()
    {
        return $this->ressource;
    }
}
La factory qui instancie la bonne ressource et la retourne à Image_Image
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
abstract class Image_Abstract_Factory
{
 
    public static function getResource($ressource,Image_Image $image)
    {
        $class = 'Image_Resources_'.$ressource;
        if(!class_exists($class))
           throw new Util_ExceptionHandler ('Ressource '.$class.' innexistante');
 
        return $class::factory($image);
 
    }
 
}
La classe de ressource dédié à GD. Elle contient les traitement basique du type redimensionnement , crop, ...
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
 
class Image_Resources_GD implements Image_Interfaces_Resource
{
 
    /**
     *
     * @var Image_Image
     */
    private $image;
 
    public function __construct($image)
    {
        $this->image = $image;
        $path =  $this->image->getPath();
        if(!empty($path))
        {
            $this->rawSource    = $this->createFromType();
            $this->width        = $this->image->getWidth();
            $this->height       = $this->image->getHeight();
        }
    }
 
    public function create($w,$h)
    {
        $width              = intval($w);
        $height             = intval($h);
        $this->rawSource    = imagecreatetruecolor($width, $height);
        $this->width        = $width;
        $this->height       = $height;
 
        $this->image->setWidth($width);
        $this->image->setHeight($height);
    }
 
    public function createFromType()
    {
        switch($this->image->getType())
        {
            case IMAGETYPE_GIF :
                $img = imagecreatefromgif($this->image->getPath());
                imagealphablending($img, true);
                return $img;
                break;
            case IMAGETYPE_JPEG :
                return imagecreatefromjpeg($this->image->getPath());
                break;
            case IMAGETYPE_PNG :
                $img = imagecreatefrompng($this->image->getPath());
                imagealphablending($img, false);
                imagesavealpha($img, true);
                return $img;
                break;
            default:
                return false;
        }
    }
 
	public function resize($w,$h)
	{
		//Redimensionner image
	}
 
    public function getRawSource()
    {
        return $this->rawSource;
    }
 
    public static function factory(Image_Image $image)
    {
        return new self($image);
    }
}
Et pour finir un exemple d'utilisation :
Code :
1
2
3
4
5
 
$image = new Image_Image('datas/Hiver.jpg');
$img = $image->getRessource();
$raw = $img->getRawSource();
$img->resize(320,240);
Jusqu'ici tout marche comme je veux. MAis pour ne pas me retrouver avec des classes énormes j'aimerais décooupé mon code en plusieurs classe. Par exemple une classe uniquement dédiée au redimensionnement, une auter à l'ajout de texte , encore une autre pour créer des captcha ...
Et c'est là que je coince, je ne sais pas trop comment m'organiser.

J'avais penser dans un premier temps à simplement passer aux classes la ressource image , faire le traitement, puis renvoyer cette ressource à la classe Image_Resources_* mais je ne sais pas si c'est un raisonnement correct.

Toute proposition est la bienvenue
grunk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 10h23   #2
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 461
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 461
Points : 2 548
Points : 2 548
Envoyer un message via Skype™ à rawsrc
Salut grunk,

Je pense que tu peux faire plus simple, tu devrais profiter de l'interface Image_Interfaces_Resource directement dans ta classe Image_Image.

J'ai modifié l'intitulé des éléments pour mieux les décrire :
En 1er tu définit ce que tu veux faire avec une image :
Code :
1
2
3
4
5
interface IImage_Services {
   function resize();
   function crop();
   function rawSource();
}
En 2nd tu définit une classe de traitement de l'image par driver :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Image_Driver_GD implements IImage_Services {
 
   private $image;
 
   function __construct(Image $pImage) {
      $this->image = $pImage;
   }
 
   function resize() {
 
   }
 
   function crop() {
 
   }
 
   function rawSource() {
 
   }
}
En en dernier tu montes ta classe Image qui se charge de masquer le traitement à l'utilisateur :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Image {
 
   const DRIVER_GD = 'gd';
 
   const TYPE_GIF  = 'gif';
   const TYPE_JPG  = 'jpg';
   const TYPE_PNG  = 'png';
   const TYPE_SWF  = 'swf';
   const TYPE_PSD  = 'psd';
   const TYPE_BMP  = 'bmp';
   const TYPE_TIFF = 'tiff';
 
   private $path;
   private $extension;
   private $ressource;
   private $type;
   private $width;
   private $height;
 
   function __construct($pPath, $pDriver = self::DRIVER_GD) {
      # définition du pilote de l'image
      switch ($pDriver) {
         case self::DRIVER_GD: $class = 'Image_Driver_GD';
      }
 
      $this->ressource = new $class($this);
   }
 
   function resize() {
      $this->ressource->resize();
   }
 
   function crop() {
      $this->ressource->crop();
   }
}
et pour reprendre ton exemple cela donnerait :
Code :
1
2
$img = new Image('/dir/file.jpg', Image::DRIVER_GD);
$img->resize();
Si pour manipuler ton image tu es obligé de passer par RawSource(), appelle directement cette fonction à la création de l'image, pas la peine d'avoir ainsi à y penser.
rawsrc est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 10h29   #3
Expert Confirmé
 
Avatar de grunk
 
Homme Olivier
Développeur Web
Inscription : août 2003
Messages : 1 837
Détails du profil
Informations personnelles :
Nom : Homme Olivier
Âge : 27
Localisation : France, Côte d'Or (Bourgogne)

Informations professionnelles :
Activité : Développeur Web
Secteur : Industrie

Informations forums :
Inscription : août 2003
Messages : 1 837
Points : 3 318
Points : 3 318
Salut et merci de ta réponse.

Ce qui me dérange avec ta solution c'est les classes Image_Driver_* ne peuvent être indépendante. Par exemple la classe GD et ImageMagik implémente les méthode standard défini dans l'interface , mais si dans ma classe GD j'ai envie de rajouter une méthode qui ne sera pas dans Imagemagik ca va être problématique.
grunk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 10h55   #4
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 461
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 461
Points : 2 548
Points : 2 548
Envoyer un message via Skype™ à rawsrc
C'est clair que cela te force à unifier toutes les implémentations de chaque driver d'image. Si tu veux malgré tout conserver les spécificités de chaque driver, il n'y a pas 36 solutions, la tienne est correcte, tu peux juste je pense oublier la classe Image_Abstract_Factory que tu peux remonter dans le constructeur de Image_Image
rawsrc est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 10h59   #5
Rédacteur/Modérateur
 
Avatar de MaitrePylos
 
Homme Gérard Ernaelsten
DBA & Dev PHP
Inscription : juin 2005
Messages : 3 174
Détails du profil
Informations personnelles :
Nom : Homme Gérard Ernaelsten
Âge : 39
Localisation : Belgique

Informations professionnelles :
Activité : DBA & Dev PHP
Secteur : Service public

Informations forums :
Inscription : juin 2005
Messages : 3 174
Points : 6 460
Points : 6 460
Tu peux aussi passer par les méthodes magiques, ce qui te permettras de définir ce que tu veux

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
class Image {
 
   const DRIVER_GD = 'gd';
 
   const TYPE_GIF  = 'gif';
   const TYPE_JPG  = 'jpg';
   const TYPE_PNG  = 'png';
   const TYPE_SWF  = 'swf';
   const TYPE_PSD  = 'psd';
   const TYPE_BMP  = 'bmp';
   const TYPE_TIFF = 'tiff';
 
   private $path;
   private $extension;
   private $ressource;
   private $type;
   private $width;
   private $height;
 
   function __construct($pPath, $pDriver = self::DRIVER_GD) {
      # définition du pilote de l'image
      switch ($pDriver) {
         case self::DRIVER_GD: $class = 'Image_Driver_GD';
      }
 
      $this->ressource = new $class($this);
   }
 
   function __get($name){
 
    return $this->ressource->$name
 
}

Code :
1
2
3
4
5
6
 
$img = new Image('/dir/file.jpg', Image::DRIVER_GD);
$img->resize();
 
$img = new Image('/dir/file.jpg', Image::DRIVER_IMAGICK);
$img->rotate();
MaitrePylos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/02/2011, 11h06   #6
Expert Confirmé
 
Avatar de rawsrc
 
Homme Martin
Dev indep
Inscription : mars 2004
Messages : 1 461
Détails du profil
Informations personnelles :
Nom : Homme Martin
Âge : 35
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Dev indep

Informations forums :
Inscription : mars 2004
Messages : 1 461
Points : 2 548
Points : 2 548
Envoyer un message via Skype™ à rawsrc
Les méthodes magiques c'est pratique à petite dose je pense, parce que pour les grandes bibliothèques ne pas bénéficier de l'auto-completion devient vite un vrai bordel. Enfin je parle pour moi car à force d'auto-completer (presque tout), je me fénéantise un peu
rawsrc est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 13h43.


 
 
 
 
Partenaires

Hébergement Web