2010-06-10 3 views
4

나는 딜레마가있다. 나는 자작 ORM을위한 핵심 구성 요소를 제공하기 위해 DI (read : factory)를 사용했습니다. 컨테이너는 요청시 데이터베이스 연결, DAO, 매퍼 및 결과 도메인 객체를 제공합니다. 여기 의존성 주입 및 작업 단위 패턴

class Monitor(){ 
    private static array modified; 
    private static array dirty; 
    public function markClean($class); 
    public function markModified($class); 
} 

ORM 클래스 자체 즉, 작업 패턴의 단위를 기반으로 ORM는 또한 클래스 (모니터)를 포함

class Mapper{ 
    public function __constructor($DAO){ 
     $this->DAO = $DAO; 
     } 

    public function load($id){ 
     if(isset(Monitor::members[$id]){ 
     return Monitor::members[$id]; 

     $values = $this->DAO->selectStmt($id); 
     //field mapping process omitted for brevity 
     $Object = new Object($values); 
     return $Object; 
     } 
    } 

class User(){ 
    public function setName($string){ 
     $this->name = $string; 
     //mark modified by means fair or foul 
    } 
} 

매퍼 및 도메인 오브젝트 클래스의 기본 개요입니다 DI 컨테이너에서 추출한 자원을 간단히 조정합니다. 새 사용자 객체를 인스턴스화하려면 다음을 수행하십시오.

$Container = new DI_Container; 
$ORM = new ORM($Container); 
$User = $ORM->load('user',1); 
//at this point the container instantiates a mapper class 
//and passes a database connection to it via the constructor 
//the mapper then takes the second argument and loads the user with that id 
$User->setName('Rumpelstiltskin');//at this point, User must mark itself as "modified" 

내 질문에 답하십시오. 사용자가 Domain Object 클래스에 값을 설정하는 시점에서 Monitor 클래스의 클래스를 "dirty"로 표시해야합니다. 내가 볼 수있는 세 가지 옵션 중 하나가 있습니다.

1 : 모니터 클래스의 인스턴스를 도메인 개체에 전달하십시오. FirePHP에서 재귀 적으로 표시되는 것으로 나타났습니다. 즉, $ this-> Monitor-> markModified ($ this)

2 : 도메인 개체에서 모니터를 직접 인스턴스화하십시오. 3 : 모니터 메소드를 정적으로 만들고 Domain 객체 내부에서 호출합니다. 이렇게하면 DI가 손상됩니다.

행동의 당신의 추천 과정이 될 것입니다 무엇 (기존 ORM을 사용하는 것보다 다른, 나는 ... 재미를 위해이 일을하고있어) 내가 그것을 결코하지 않았다

+0

ORM은 반환하는 객체의 참조를 유지합니까? 그렇지 않은 경우 모니터가 ORM에있는 이유는 무엇입니까? 엔티티가 자신의 모니터를 가지고 있다면, CRUD 작업을 위해 모두 ORM으로 다시 전달되면 ORM이 모니터를 변경하여 루프합니다. –

+0

아니요, 모니터는로드 된 모든 클래스의 레코드를 유지하므로 $ User1과 $ User2는 동일한 레코드 인 경우 Monitor의 동일한 객체를 가리 킵니다. ORM 자체는 Mappers 등의 상호 작용을 처리하기위한 외관 일뿐입니다. ORM 루프 저장시 변경 사항 모니터링 – sunwukung

+0

패턴 사용에 대해 혼란스러워합니다. DI *를 ORM에 넣으면 종속성 주입이 중단됩니다. 그렇지 않습니까? ORM은 전통적인 ORM보다는 도메인 객체를위한 팩토리입니다. 도메인 객체 팩토리에 모니터를 배치하지 않습니다.이 시나리오에서는 정적으로 만들 것입니다. 당신의 패턴이 이루고있는 것을 오해한다면, 사과드립니다. –

답변

1

알겠습니다. 이것에 대해 :

$user = new User; 
$monitoredUser = new Monitor($user); 

//at update in class Monitor: 
Monitor::markDirty($this); 

이제 모니터를 데코레이터로 사용합니다. 들어오는 요청을 처리하는 사용자 객체 나 다른 객체 주위에 셸을 추가합니다. 개체가 업데이트되면 모니터에 의해 더러움으로 표시되지만 모니터는이 메서드에 대해 정적 메서드를 사용하므로 현재 클래스 범위 내에 남아 있으므로 재귀를 피할 수 있습니다.

+0

흥미로운 각도이지만 API가 더 어려울 수도 있습니다. 결과 - 모니터를 수동으로 업데이트해야합니다. 이상적으로 사용자는 ORM에서 사용자를 얻고 속성을 변경하면 자동으로 모니터링됩니다. 와우의 구현은 static (external) 호출을 사용하는 것을 보았습니다.하지만 그것은 잘못되었습니다. – sunwukung

+0

이것을 위해 리플렉션을 사용할 수도 있습니다. 액세서가 호출 된 경우 사용자에게 요청을 전달하는 __call() 메서드를 구현합니다. –

+0

아마도 영감을 얻기 위해 : 나는 대안적인 우와 패턴을 제안했다 : http://www.gabordemooij.com/unit_of_work, 그리고 나 자신의 ORM을 가지고있다. http://www.redbeanphp.com –

0

생각을, 당신의 모니터 클래스에 해당하는 것으로 보인다 에 " 옵저버 "디자인 패턴. 이렇게하면 클래스를 더티라고 표시하도록 Monitor 클래스에 요청할 필요는 없지만 혼자 수행해야합니다.

제가 PHP로 해본 적이 없지만, PHP로이 디자인 패턴을 구현할 수있는 방법을 Google에서 찾을 수 있다고 확신합니다.

+0

물론 이것은 기본적으로 설정자를 사용하는 것과 같습니다. 내 유일한 문제는 재귀 루프를 설정한다는 것입니다 (Entity에 대한 참조가 Monitor에 있고 Monitor에 대한 참조가 Entity에 있기 때문에). – sunwukung

0

큰 질문입니다. markModified() 내부에서 어떤 일이 발생합니까? 코드에 복사하여 시도했지만 오류가 표시되지 않습니다. 그래서 퍼즐 한 조각이없는 것 같아요?

+0

markModified는 $ this에 대한 참조를 Monitor의 $ _modified 배열에 저장하기 만합니다. 오류는 아니지만 FirePHP의 플래그입니다. Monitor에 Entity ref가 포함되어 있고 Entity에 Monitor ref가 포함되어있는 경우 일종의 재귀 호출입니다. – sunwukung