IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

[POO] Petit problème de conception


Sujet :

Langage PHP

  1. #1
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 692
    Points : 20 244
    Points
    20 244
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  2. #2
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  3. #3
    Modérateur
    Avatar de grunk
    Homme Profil pro
    Lead dév - Architecte
    Inscrit en
    Août 2003
    Messages
    6 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Lead dév - Architecte
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2003
    Messages : 6 692
    Points : 20 244
    Points
    20 244
    Par défaut
    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.

  4. #4
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    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

  5. #5
    Modérateur

    Avatar de MaitrePylos
    Homme Profil pro
    DBA
    Inscrit en
    Juin 2005
    Messages
    5 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : Belgique

    Informations professionnelles :
    Activité : DBA
    Secteur : Service public

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 497
    Points : 12 600
    Points
    12 600
    Par défaut
    Tu peux aussi passer par les méthodes magiques, ce qui te permettras de définir ce que tu veux

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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();

  6. #6
    Expert éminent sénior
    Avatar de rawsrc
    Homme Profil pro
    Dev indep
    Inscrit en
    Mars 2004
    Messages
    6 142
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Dev indep

    Informations forums :
    Inscription : Mars 2004
    Messages : 6 142
    Points : 16 545
    Points
    16 545
    Billets dans le blog
    12
    Par défaut
    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

Discussions similaires

  1. Petit problème de conception
    Par Falcor dans le forum UML
    Réponses: 2
    Dernier message: 13/12/2009, 13h36
  2. Réponses: 0
    Dernier message: 09/11/2008, 15h33
  3. [LINQ & WCF] Petit problème de conception
    Par tomlev dans le forum Général Dotnet
    Réponses: 20
    Dernier message: 19/03/2008, 10h11
  4. Un petit problème de conception du code
    Par diamonds dans le forum NetBeans
    Réponses: 2
    Dernier message: 27/02/2007, 17h40
  5. Petit problème de conception sur access
    Par coooookinette dans le forum Modélisation
    Réponses: 3
    Dernier message: 18/12/2005, 19h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo