0

StackOverflow에 처음있는 것이고, 내 질문에 noobish가 없기를 바랍니다! 이 문제를 해결하기 위해 실제로 시도한 적이 없으며 항상 대신 생성자 대신 setter 메서드를 사용합니다. 그러나 이제는 더 나은 패턴을 찾아야합니다. :) 검색을 시도했지만 만족스러운 답변을 얻을 수 없었습니다. (생성자 순환 종속성을 없애기

기본적으로 모든 종속성을 함께 연결하는 것으로 가정되는 컨테이너 클래스와 모든 클래스 (A, B,. ..)뿐만 아니라 컨테이너에서 "자신의 내부에"다른 클래스에서 액세스 할 수 있어야합니다.

<?php 

class MyContainer 
{ 
    function __construct(A $a, B $b){ 
     $this->a = $a; 
     $this->b = $b; 
    } 

    function getA(){ return $this->a; } 
    function getB(){ return $this->b; } 
} 

class A 
{ 
    function __construct(MyContainer $myc){ $this->myc = $myc; } 
    function useA(){ echo "A"; $this->myc->getB()->doSmt(); } 
    function doSmt(){ echo "A smt"; } 
} 

class B 
{ 
    function __construct(MyContainer $myc){ $this->myc = $myc; } 
    function useB(){ echo "B"; $this->myc->getA()->doSmt(); } 
    function doSmt(){ echo "B smt"; } 
} 

?> 

을 이제는 인스턴스화하는 것은 불가능 MYC는 A와 B가 필요하며, A와 B는 MYC을 필요로하기 때문이다.

어떻게 해결할 수 있습니까? 교수님은 순환 의존성이 설계 문제 일 가능성이 높을 때 그 문제를 해결할 수 없다고 말씀하셨습니다. A와 B의 존재는 실제로 MyCollection에 의존하고 그 반대도 마찬가지입니다.

P. 깨끗하고 합리적인 방법으로 수행 할 수 있다면 DI를 사용하여 문제를 해결하려고합니다. 나는 공장의 팬이 아니다! :)

도움을 주셔서 감사합니다.

답변

2

그래, 디자인 문제입니다. 당신 싶어 당신이 이미 가지고있는 코드에서 그것을 할 경우

, 당신은 이런 식으로 그것을 할 수 :

class MyContainer 
{ 
    function __construct(A $a, B $b){ 
     $a->setContainer($this); 
     $b->setContainer($this); 
     $this->a = $a; 
     $this->b = $b; 
    } 

    function getA(){ return $this->a; } 
    function getB(){ return $this->b; } 
} 

class A 
{ 
    function setContainer(MyContainer $myc){ $this->myc = $myc; } 
    function useA(){ echo "A: "; $this->myc->getB()->doSmt();echo "<br />"; } 
    function doSmt(){ echo "A smt<br />"; } 
} 

class B 
{ 
    function setContainer(MyContainer $myc){ $this->myc = $myc; } 
    function useB(){ echo "B: "; $this->myc->getA()->doSmt();echo "<br />"; } 
    function doSmt(){ echo "B smt<br />"; } 
} 

그러나 나는 그것이 좋은 방법입니다 생각하지 않습니다.

정확히 무엇을하려합니까?

아마 관찰자 패턴이 당신의 특별한 문제를 해결합니까?

<?php 
interface IObserver { 
    function doSmt(); 
} 
class Notifier{ 
    private $_observers = array(); 
    function register(IObserver $observer) { 
     $this->_observers[] = $observer; 
    } 
    function notify() { 
     foreach($this->_observers AS $observer) { 
      $observer->doSmt(); 
     } 
    } 
} 

class A implements IObserver { 
    function doSmt() { 
     echo "A smt<br />"; 
    } 
} 
class B implements IObserver { 
    function doSmt() { 
     echo "B smt<br />"; 
    } 
} 


$a = new A(); 
$b = new B(); 

$notifier = new Notifier(); 
$notifier->register($a); 
$notifier->register($b); 

$notifier->notify(); 

이제 옵서버 등록 순서에 따라 전화 순서를 변경할 수도 있습니다. 또는 통지하기 전에 정렬하려는 경우. 그것은 당신에게 달려 있습니다.

자세한 정보 나 예상 출력을 제공 할 수 있다면 좋을 것입니다. 나는 내가 준 코드의 첫 번째 방법을 시도하기 때문에

(코드의 기준) :

$a = new A(); 
$b = new B(); 

$container = new MyContainer($a, $b); 
$container->getA()->useA(); 
$container->getB()->useB(); 

또는

$a = new A(); 
$b = new B(); 

$container = new MyContainer($a, $b); 
$container->getA()->doSmt(); 
$container->getB()->doSmt(); 
+0

안녕하세요, 답변에 대한 감사합니다! 클래스 A는 그 내부에서 B 메소드를 호출 할 수 있어야하며 그 반대도 마찬가지입니다. 나는 내일 질문에 더 많은 정보를 추가 할 것이다! 고마워요 :) – MarcoR88

+0

좋아,하지만 첫 번째 코드 블록은 코드를 기반으로하는 방법을 달성 할 수 있습니다 :) 하지만 두 클래스 (classX)의 공통 인자를 추상화하여 새 클래스에 넣어야합니다 또는 뭔가. 그리고 둘 다 클래스 X에 의존하게하십시오. 나는 당신이 성취하려는 것을 이해하지 못하기 때문에. 나는 지금 당신을 도울 수 없다. :) – Muqito

+0

하지만 코드를 리팩토링하고 공통 인자를 추출해야한다. – Muqito

관련 문제