2010-12-16 3 views
3

나는 비슷한 질문을했다. 뒤로 : Using the Data Mapper Pattern, Should the Entities (Domain Objects) know about the Mapper? 그러나 일반적이었고 나는 Doctrine2와 함께 몇 가지 작업을 수행하는 방법에 특히 흥미가있다..Doctrine2 모범 사례, 기업은 서비스를 사용해야합니까?

여기 간단한 예제 모델의 각 ThingUser에서 Vote을 가질 수하는 User 개 이상의 Vote하지만 마지막 Vote 수를 주조 할 수있다. 다른 데이터 (Msssage 등)가 Vote과 관련되어 있기 때문에 두 번째 Vote이 삽입되면 원래 Vote은 업데이트 할 수 없으므로 교체해야합니다.

public function setThing(Model_Thing $thing) 
{ 
    $this->thing = $thing; 
    $thing->votes[] = $this; 
} 

User을 보장하는 유일한 계산 마지막 Vote이 뭔가가 나에게 보인다

public function addVote($vote) 
{ 
    $vote->entity = $this; 
} 

그리고 Vote이 관계를 설정을 담당 : 현재

Thing이 기능이 Thing은 보장해야하며 not some service layer입니다.

public function addVote($vote) 
{ 
    foreach($this->votes as $v){ 
    if($v->user === $vote->user){ 
     //remove vote 
    } 
    } 
    $vote->entity = $this; 
} 

그래서 어떻게 도메인 모델 내에서 Vote을 제거합니까 :

그래서, 모델의 새로운 Thing 기능을 그 유지?NULL을 수락하기 위해 Vote::setThing()을 풀어야합니까? Thing이 투표를 제거하는 데 사용할 수있는 서비스 계층을 사용해야합니까? 투표가 누적되기 시작하면 foreach은 느려질 것입니다. Thing을 사용하여 전체 컬렉션을로드 할 필요없이 Vote을 검색 할 수있게해야합니까?

가벼운 서비스 레이어를 사용하는 것이 분명합니다. 그러나 은 Doctrine2에서 이런 유형의 것을 처리하는 더 좋은 방법입니까, 아니면 올바른 방향으로 가고 있습니까?

답변

7

서비스 계층에 대해 투표합니다. 저는 종종 엔티티 자체에 많은 논리를 추가하려고 애 쓰면서 혼란스러워했습니다. EntityManager에 대한 액세스가 없다면 쿼리 로직을 수행 할 수 없으며 몇 가지 레코드 만 필요할 때 많은 O (n) 연산 또는 전체 관계 세트를 지연로드하는 것을 볼 수 있습니다. 절름발이가 DQL이 제공하는 모든 이점과 비교할 때).

빈혈 도메인 모델이 항상 안티 패턴이라는 아이디어를 얻으려면 도움이 필요하면 Matthew Weier O'Phinney의 this presentation 또는 this question을 참조하십시오.

내가 용어를 잘못 해석 할 수는 있지만 엔티티가 도메인 모델에서 허용되는 유일한 개체 여야한다고 완전히 확신 할 수는 없습니다. Entity 개체와 해당 서비스의 합계가 모델을 구성한다고 쉽게 생각할 것입니다. 나는 반 패턴이 우려의 분리에 거의 관심을 기울이지 않는 서비스 계층을 작성하게 될 때 발생한다고 생각한다.

나는 종종 내 모든 엔티티가 프록시 서비스 계층에 대한 몇 가지 방법 개체를 가지고있는 아이디어를 설레했습니다 교리는 객체 수화에 어떤 종류의 콜백 이벤트 시스템을 가지고 있지 않기 때문에, 그러나

public function addVote($vote) 
{ 
    $this->_service->addVoteToThing($vote, $thing); 
} 

을, I 서비스 객체를 삽입하는 우아한 방법을 찾지 못했습니다.

+0

링크를 체크 아웃합니다. 서비스 레이어를 모델의 일부로 간주 할 수 있다는 데 동의합니다. 파울러 (Fowler)는 자신의 빈혈 도메인 모델 (Alemic Domain Model) 게시물에서도 동일하게 말합니다. 엔티티가 내부 투표를 추가하는 것을 (현재) 선호하는 반면, 컬렉션을 통해 미친 검색 대신 투표를 찾거나 삭제하기 위해 서비스 레이어에 프록시를 지정합니다. 나는 그 질문이 - 서비스 객체를 주입하는 방법이라고 생각한다. 아마도'$ em-> getRepository()'와 같은 정적 함수일까요? –

+0

그 프레젠테이션을 진행할 기회가 있습니다. 정말 좋은 정보입니다. Zend Framework 아키텍처를 생각 나게합니다. heaver 서비스 레이어가 단위 테스팅의 용이성에 영향을 미칠 수있는 방법을 여전히 처리합니다. 다시 말하지만, 훌륭한 링크. –

+0

당신이 여기에 접근하는 데 관심이 있습니다. 또한 서비스를 내 엔터티의 속성으로 사용하고 엔터티 자체 (지속성을 처리하기 위해 서비스를 사용함)에 '저장'과 같은 메서드를 구현하는 아이디어를 가지고 놀고 있습니다. 이것은 조금 activeRecord (ish) 인 것 같습니다. 그래서 그것을하지 않았습니다. 대안은 서비스 객체를 사용하지만 엔티티를 INTO 대신 전달합니다. – calumbrodie

6

내 조언은 같은 종류의 그것의 인터페이스를 EntityRepository에 모든 쿼리 로직을 넣고 확인하는 것입니다 : 당신이에 대한 단위 테스트에서 인터페이스를 사용할 수 있습니다

class BlogPostRepository extends EntityRepository implements IBlogPostRepository {} 

그런 식으로 서비스 객체와 EntityManager에 대한 의존성이 필요하지 않습니다.

+0

+1 리포지토리/서비스 레이어/등을 테스트하는 가장 좋은 방법이 방정식에 추가되었는지 궁금합니다. –

관련 문제