2012-03-05 2 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를 잠글 수 있도록하고 싶습니다 '코드를 복제해야합니다. 다음 나는

 


    //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, 정식 지적했지만 나는 그것들을 보았다. 그럼 어떻게 파일을 잠그라고 제안 하시겠습니까? 또는 압축되지 않은 크기에 쉽게 액세스 할 수 있도록 압축 기능을 추가하십시오. 반복기와 내가 확실히 사용할 수있는 모든 것들이 있지만 하나의 특정 파일 형식으로 작업 할 때는 더 많은 코딩을해야합니다. –

답변

0

잠긴 클래스의 유형이 중요하지 않은 경우 Decorator 패턴을 사용할 수 있습니다.

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

이렇게하면 논리를 복제하지 않습니다. 단점은 데코 레이팅 된 유형이 필요한 메소드에서 데코 레이팅 된 인스턴스를 사용할 수 없다는 것입니다 (적절한 인터페이스를 추가하고 모든 호출을 위임하지 않는 한).

전략 패턴은 또 다른 옵션이 될 것입니다 :

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

그래, 내가 데코레이터 패턴을 좋아하는데, 이것은 갈 좋은 방법 같아. 나는 원래 각 타입의 객체를 잠그는 방법을 '알고있는'잠금 클래스의 '세트'를 작성하려고 생각했다. Gordon에게 도움을 주셔서 감사합니다. 이 기능을 사용하면 파일 기능을 복제하지 않아도됩니다. 훨씬 더 편리합니다. –

0

전략 패턴을 살펴보아야합니다. Lockability 전략의 상속을 시도하기보다는 그것을 사용하는 것을 고려하십시오.