2014-12-26 4 views
2

현재 첫 번째 PHP/Laravel 4 프로젝트를 진행 중입니다. 제 3 자 라이브러리에 Eloquent 지원을 추가하기 위해 저장소 클래스를 개발 중입니다.Laravel extends Eloquent 및 타사 클래스

My EloquentStorage 클래스는 라이브러리에서 AbstractStorage 클래스를 확장하며 대부분의 AbstractStorage 메소드를 사용합니다. 이제 새로운 EloquentStorage 클래스에 Eloquent 지원을 추가하기 위해 PHP가 다중 상속을 지원하지 않는다는 사실에 직면했습니다.

로 확장하지 않고 설득력 모델을 정의하는 적절한 방법이 있나요 :

class MyClass extends Eloquent {} 

그리고이하지 않으면 내가 설득력을 제 3 자 클래스를 확장하며 확장 할 필요가있을 때, 어떻게 이러한 상황에 대처하기 위해? 아마도 Laravel의 IoC를 사용하고 있을까요?

답변

1

귀하의 모델은 Eloquent에서 연장되어야하며 repository을 통해 액세스해야한다고 생각합니다. 저장소에 $storage 속성이있을 수 있으며 AbstractStorage 구현에서 적절한 메소드를 호출해야합니다. 아래는 실제 코드보다 더 많은 pseudo이지만 업데이트 작업을 위해 구현을 어디에 연결할 수 있는지 보여줍니다.

class MyClass extends Eloquent 
{ 
    /* Normal Eloquent model implementation */ 
} 

class MyRepository 
{ 
    protected $storage; 
    protected $myClass; 

    public function __construct(MyClass $myClass, AbstractStorage $storage) 
    { 
     $this->myClass = $myClass; 
     $this->storage = $storage; 
    } 

    public function update($id, $data) 
    { 
     // This is just an example operation, basically here's your chance to call 
     // the 3rd-party implementation. Here is pre-eloquent update, but can be 
     // after 
     $this->storage->update($id, $data); 

     // Use the empty Eloquent class property instance to obtain an instance of 
     // the requested model 
     $instance = $this->myClass->find($id); 
     // set instance properties 
     $instance->save(); 

     // Example post-eloquent update 
     $this->storage->update($id, $data); 
    } 
} 

class MyStorage extends AbstractStorage { /* Your Storage Implementation */ } 

$repo = new MyRepository(new MyClass, new MyStorage); 
// Update item id 42's foo property 
$repo->update(42, [ 'foo' => 'bar' ]); 

이 방법의 이점은 저장소 자체의 구조가 서비스 공급자를 통해 IOC의 오프로드 될 수 있고, 실행은 자동으로 될 것이다 수단 제어기/폼 검증 등의 내부에 주입 할 수 있다는 것이다 타사 라이브러리의 기본 복잡성을 나머지 시스템에서 숨 깁니다 (리포지토리는 타사 추상화를 leaking에서 유지하는 데 도움이됩니다).

또 다른 이점은 전혀 상관없는 제 3 자 코드와 관련이있는 웅변 모델에 특별한 코드가 필요 없다는 것입니다. 모든 로직은 단일 지점에 캡슐화되며 여러 모델간에 공유 할 수도 있습니다. 타사 제공 업체를 변경하고 싶습니까? AbstractStorage의 새 구현을 작성하고 서비스 공급자를 업데이트하면 완료됩니다.

다른 이점 중 하나는 테스트 가능성이 향상되었습니다. 정적으로 웅변 모델을 직접 정적으로 사용하는 대신 ($user = User::find($id)) 대신 리포지토리 개체를 조작하게됩니다 ($user = $this->repo->find($id)). Eloquent를 테스트하거나 데이터베이스를 사용하지 않고 저장소를 쉽게 조롱하고 테스트 할 수 있기 때문에 모든 컨트롤러 경로에 대한 통합 테스트를 작성하고 코드베이스 변경으로 비즈니스 규칙을 깨는 순간을 알 수 있습니다.

+0

이것은 두려운 접근이며, 지금 시도하고 결과로 돌아올 것입니다. 감사합니다 @ 와처 –