2012-03-05 42 views
1

私はいくつかのクラスを書いて、私が何をすべきかについての道を分岐しました。私の基本的な質問は、非常に似た機能を持つクラス間でコードを複製しないようにするにはどうすればいいですか?私にとって今のところ、形質は選択肢ではありません。とにかくあまりにも多くの人が助けてくれるとは思いません。PHPクラスモデリングの問題

私は以下のクラスを実装しています。

 

    //either a directory or a file on the file system 
    class FileSystem_Object{ 
     //the size of the class in bytes 
     public function getSize(){} 

     //same as phps native realpath 
     public function getRealPath(){} 
    } 

    //a zip file on the file system, e.g. files that end in .zip extension. 
    class FileSystem_Object_Zip extends FileSystem_Object{ 
     //returns size of all files if they were to be uncompressed, in bytes 
     public function getUncompressedSize(){} 
    } 

    //a singleton file that keeps track of only one object copy of a file 
    class FileSystem_Manager{} 
 

これらのクラスは、SPLFileObject型の機能をいくつか提供します。私はその時点複数のオブジェクトを作成する私を避けるため、

 

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

 

私はそれが新しいクラスオブジェクトを返すか、すでにそのパスに割り当てられたオブジェクトを返しますどちらかgetFileSystemObjectメソッドを呼び出すたびものの以下のようなものを行うことができますファイルシステム上の同じパスにコピーします。 (おそらくベストアイデアではないかもしれませんが、それは私が一緒に行ったものです)。

ここでは少し問題になっています。

オブジェクトをロックするために使用する別のクラスがあります。今私がロックしている唯一のオブジェクトは、ディレクトリかファイルかにかかわらず、filesystem_objectsです。これは、ロックしようとしているPHPプロセスのプロセスIDに基づいてファイルのロックファイルを作成するだけで十分です。

 


    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; 
     } 
    } 

 

私が今直面している問題は、私は同様にロックすることができZipファイルオブジェクトを作成したいということであり、私にはかなり上の任意のファイル/ディレクトリが、私DONをロックできるようにしたいのですが'Tはコードを複製する必要があります。次のうちどれ私が

 


    //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 
    } 

 

は今、私はオプション3に傾いていますが、その後、私は自分のライブラリーの「ロッカー」部分を持っている必要がありますので、私はそれを行うには好きではないだろう唯一の理由がある行う必要があります私がファイルシステムのものを使いたいときはいつでも。より強固に結合されるだろう。

デザインに関するコメントがありますが、「SplFileObjectはこの/すべての/ほとんどのことをしています」と言うでしょう。私はここに例を挙げていますが、私が実装したすべてのメソッドがここにあるわけではありませんので、これは私が書いた唯一の機能ではありません。しかし、これらすべてのコメントは、この問題を回避する設計に着陸させる可能性があるため、歓迎します。

ありがとうございました

+0

あなたがそこに車輪の再発明を続ける前に 'SplFileObject'、' ZipArchive'、 'FileSystemIterator'と' DirectoryIterator'を見てしたい場合があります。 ) – Gordon

+0

@Gordon、正式には記載されていますが、私はそれらを見てきました。ファイルロックをどうやってするといいですか?または、圧縮されていないサイズに簡単にアクセスできるように、zipファイル固有の機能を追加しますか?イテレーターと私が間違いなく使うことができるものはありますが、特定のファイルタイプを扱う場合は、さらにコーディングを行う必要があります。 –

答えて

0

ロックされたクラスのタイプが関係ない場合は、デコレータパターン(例:

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); 
    } 
} 

このように、論理を複製していません。欠点は、装飾型を必要とするメソッドで装飾されたインスタンスを使用できないことです(適切なインターフェイスを追加してすべての呼び出しを委任しない限り)。

Strategyパターンは、別のオプションのようになります。

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

ええ、私はデコレータのパターンが好きです、これは良い方法のように聞こえる。私はもともと、特定のタイプのオブジェクトをロックする方法を「知っている」ロッククラスの「セット」を書くことを考えていました。ゴードン助けてくれてありがとう。これは、ファイルの機能を複製しないために役立ちます。はるかに便利です。 –

0

私は戦略パターンを調べるべきだと思います。 Lockability戦略を継承しようとするのではなく、その構成を使用することを検討してください。