2012-03-05 1 views
1

J'ai écrit quelques cours et je suis passé à la bifurcation sur ce que je devrais faire. Ma question de base est, comment puis-je éviter de dupliquer mon code à travers les classes avec des fonctionnalités très similaires? Les traits ne sont pas une option pour moi en ce moment, et je ne pense pas qu'ils aideraient trop ici de toute façon.Problème de modélisation de la classe PHP

J'ai les classes suivantes implémentées. Ces classes sortof me fournissent certaines fonctionnalités de type SPLFileObject. Je peux faire le genre suivant de choses

 

    $object = 
     FileSystem_Manager::getInstance() 
     ->getFileSystemObjecT('/some/path/to/file/or/directory/'); 

 

Chaque fois que j'appelle la méthode getFileSystemObject il soit retourner un nouvel objet de classe ou retourner un objet qui a été attribué à ce chemin déjà, ainsi me évitant de créer plusieurs objets ce point au même chemin sur le système de fichiers. (peut-être pas la meilleure idée, mais c'est ce que je suis allé avec.)

Voici où nous arrivons à la question un peu.

J'ai un autre ensemble de classes que j'utilise pour 'verrouiller' des objets. À l'heure actuelle, les seuls objets que je verrouille sont les fichiers_fichiers_objets, qu'ils soient des répertoires ou des fichiers. Cela fonctionne assez simplement en créant un fichier de verrouillage pour le fichier basé sur l'ID de processus du processus PHP essayant de le verrouiller.

 


    inteface Lockable_Object{ 

     public functon getLockableIdentifier(); 
    } 

    class Lockable_FileSystemObject implements Lockable_Object{ 

     /** 
     * I return a false here if the file doesn't exist 
     * so any other processes trying to lock this file will 
     * know they can no longer lock it because it has moved 
     * or been renamed for some reason. 
     */ 

     public functon getLockableIdentifier(){ 
      if(file_exists($this->_fullFilePath)){ 
       return $this->getRealPath(); 
      } 
      return false; 
     } 
    } 

 

Le problème que je face aujourd'hui est que je voudrais créer un objet fichier Zip qui peut être verrouillé aussi bien, et je voudrais être en mesure de verrouiller à peu près tout fichier/répertoire mais je DON Je ne veux pas avoir à dupliquer le code. Lequel des éléments suivants dois-je faire

 


    //Option 1 
    class Lockable_Object_Zip extends FileSystem_Object_Zip 
           implements Lockable_Object{ 
     //In here I would have to duplicate the getLockableIdentifier method and do that 
     //for every file type i decide to make in the future 
    } 

    //Option 2 
    class Lockable_Object_Zip extends Lockable_FileSystemObject 
     //In here I would have to duplicate all the zip functionality coded into 
     //FileSystem_Object_Zip 
    } 

    //Option 3 
    class FileSystem_Object implements Lockable_Object{ 
     //build in the 'lockablity' into the base class 
    } 

 

En ce moment, je penche vers l'option 3, mais la seule raison pour laquelle je ne voudrais pas faire cela parce que je voudrais avoir la partie « Locker » de ma bibliothèque chaque fois que je veux utiliser le système de fichiers; ce serait plus étroitement couplé.

Je suis sûr que vous aurez des commentaires sur le design et certains diront que "SplFileObject fait tout/presque tout ça". J'ai inclus des méthodes ici pour des exemples et pas toutes les méthodes que j'ai implémentées ici donc ce n'est pas la seule fonctionnalité que j'ai écrite. Tous ces commentaires et bien d'autres sont les bienvenus, car ils pourraient m'abattre sur un design qui permettra d'éviter toute cette question.

Merci

+0

vous pouvez jeter un oeil à 'SplFileObject',' ZipArchive', '' FileSystemIterator' et DirectoryIterator' avant de continuer à réinventer la roue là;) – Gordon

+0

@Gordon, dûment noté mais j'ai regardé ceux-ci. Comment suggérez-vous que je fasse le verrouillage de fichier alors? Ou ajoutez la fonctionnalité spécifique de fichier zip pour un accès facile à la taille non compressée? Les itérateurs et tout ce que je peux certainement utiliser, mais quand il s'agit de travailler avec un type de fichier spécifique, je dois encore faire plus de codage. –

Répondre

0

Si le type de classes verrouillées n'a pas d'importance, vous pouvez utiliser un motif Décorateur, par ex.

class Lockable 
{ 
    protected $lockable; 

    public function __construct($lockable) 
    { 
     $this->lockable = $lockable; 
    } 

    public function lock() 
    { 
     // .. your code to lock $this->lockable 
    } 

    public function __call($method, $args) 
    { 
     return call_user_func_array(array($this->lockable, $method), $args); 
    } 
} 

De cette façon, vous ne dupliquez pas la logique. L'inconvénient est que vous ne pouvez pas utiliser l'instance décorée dans les méthodes nécessitant le type décoré (sauf si vous ajoutez des interfaces appropriées et déléguez tous les appels).

Le modèle de stratégie serait une autre option:

class LockingStrategy 
{ 
    public function lock($fileSystemObject) 
    { 
     // your code to lock $fileSystemObject 
    } 
} 

class ZipFile 
… 
    public function __construct(LockingStrategy $strategy) 
    { 
     $this->lockingStrategy = $strategy; 
    } 
    public function lock() 
    { 
     $this->lockingStrategy->lock($this); 
    } 
} 
+0

Ouais j'aime le motif décorateur, cela semble être un bon moyen d'y aller. À l'origine, je pensais écrire un «ensemble» de classes de verrouillage que chacun «savait» verrouiller un certain type d'objet. Merci pour l'aide Gordon. Cela m'aidera à ne pas dupliquer la fonctionnalité du fichier. Beaucoup plus pratique. –

0

Je pense que vous devriez regarder dans le modèle de stratégie. Envisagez d'utiliser la composition d'une stratégie de verrouillage plutôt que d'essayer de l'hériter.

Questions connexes