2012-08-13 7 views
1

저는 PHP 응용 프로그램 전체에서 생성자 종속성 주입을 연습 해 왔습니다. 나는 객체 생성을위한 코드를 쓰레기로 만들고 싶지 않았고, 공장을 구출하기 위해, 또는 적어도 나는 생각했다.공장에서의 의존성 삽입

구성 요소를 공장으로 배선하는 방법을 설정 한 다음 일부 공장에서는 다른 공장을 사용하여 종속성을 확보하기 시작하여 모든 작성 코드를 한 곳에서 유지합니다. 그러나 일단 공장이 서로를 사용하기 시작하면 (또는 아래 코드에서와 같이) 원형 의존성 문제가 발생하여 간단히 해결할 수 없습니다. 응용 프로그램과

class MapperFactory 
{ 
    public function create($type) 
    { 
     switch (true) { 
      case 'Item': 
       $mapper = new ItemMapper(
        $this->create('Field') 
       );    
       break; 
      case 'Field': 
       $mapper = new ItemMapper(
        $this->create('Item') 
       ); 
       break; 
      default: 
       throw new Exception('Unknown mapper'); 
     } 
     return $mapper; 
    } 

} 

$mf = new MapperFactory(); 
$mf->create('Item'); 

그것의 간단한 예,하지만 점점 더 일반적인 문제 : 예를 들어, 내 MapperFactory (그들은 전체 객체 그래프 '열망로드'를 구축하기 위해 서로를 필요로) 다른 매퍼와 매퍼를 주입 자체를 사용 개발 중입니다. 다시 PHP (설치 Xdebug는)에서 오류입니다 : PHP는 불평을하는 이유 (이 TBH 오는 보지 않았더라도)

Fatal error: Maximum function nesting level of '100' reached, aborting! 

완전 이해합니다.

내 질문은 완전히 공장의 요점을 놓쳤는가? 나는 공장을 올바르게 사용하고 있는가? 그렇지 않은 것처럼 보일지 모르지만 원형 의존성 (꽤 중요하지만) 이외에 공장은 주 애플리케이션에서 모든 건설/배선 논리를 숨기는 우아한 솔루션입니다.

+0

내가이 공장에 문제가 생각하지 않습니다해야합니다. 첫째, "전환 (true)"부분을 얻지 못합니다. "switch ($ type)"가 아니어야합니까? 둘째로, 코드 (끝까지 읽으면)가 끝없이 반복됩니다. 아마도 해당 인스턴스 변수를 사용할 준비가되었을 때만 하위 필드 또는 하위 항목을 만들어야합니다. 또는 재귀를 끝내는 무언가를 생각해 내십시오. – Marvo

+0

'switch (true) ... '는 당신이 쓰려고했던 것이 아닙니다. 그러나'switch ($ type) '을 사용해도'$ type'이'Field' 또는'Item'이면 무한 루프가됩니다. – Yoshi

답변

1

의존성을 주입하기 위해 설정기를 사용해 볼 수 있습니다.

$itemMapper = new Mapper(); 
$fieldMapper = new Mapper(); 
$itemMapper->setRelatedMapper($fieldMapper); 
$fieldMapper->setRelatedMapper($itemMapper); 

을 그리고 단지 매퍼를 반환하는 스위치를 사용 : 그럼 당신은이 같은 두 매퍼를 만들 것입니다. 개체를 만들 때 순환 종속성을 제거해야합니다.

데이터베이스에 연결하는 일종의 OR/M 것으로 이것을 수행한다면, Doctrine2 나 Propel과 같은 것을 조사해야합니다. 휠을 발명 할 때의 문제를 해결하려면 이미 시도되고 테스트 된 솔루션입니다.

+0

그래, 나는 의존자를 '요구 사항'으로 간주하여 생성자에서 필요로한다고 생각하지만 세터와 함께 실험했다. 그러나 확실히 나는 다시보아야 할 것이 있습니다. ORM은 SOAP과 REST 서비스를 통해 객체를 유지해야하므로 유연성을 유지해야한다. – user1595982

+0

네, 생성자는 관계를 강화하는 방법이지만, "item"이 "item"을 만드는 "field"를 생성하기 때문에 루프를 생성합니다. setter를 사용하면 객체 간의 참조, 그리고 var 덤프 또는 이와 유사한 객체가 무한한 객체 계층 구조를 나타내지 만 적어도 중단되지는 않습니다. 무한대가 아닌 두 개의 인스턴스 만 생성하면 ... – Pinetree

0

MapperFactorycreate 메서드는 끝없는 루프를 발생시킵니다.

switch(true) { 
    case 'Item' : // this will always be selected http://php.net/manual/en/language.types.type-juggling.php 
    $mapper = new ItemMapper(
     $this->create('Field'); // Forces loop, 
    ); 

스위치가 TRUE 일치를 찾고 있다면, 다음의 경우 작업이 부울

switch(true) { 
    case $type == 'Item' : 
    // ... 
    break; 
    case $type == 'Field' : 
    // ... 
} 
+0

예, 죄송합니다. 질문의 문맥 (순환 의존성)을 감안할 때 이것은 용서할 수 없습니다. switch ($ type) 여야합니다. – user1595982

관련 문제