2010-03-17 6 views

답변

4

당신이 찾고있는 것은 사이클을 탐지하는 그래프 - 탐색 알고리즘입니다. 하나의 간단한 접근 방식 (단일 스레드 시나리오에서만 작동)은 글로벌/정적 카운터를 유지하여 각 최상위 레벨 update() 호출이 고유 식별자를 갖도록합니다. 각 관찰자는 이미 주어진 식별자 (ID)로 업데이트를 처리했는지 여부를 추적하고 그 경우 무시합니다. 즉, update 메소드를 특정 업데이트의 ID 번호가있는 매개 변수로 확장해야합니다.

2

관찰자가 수신 한 이벤트 (또는 ID)를 일부 임시 저장소에 추가하고 새로운 이벤트가 수신 될 때마다 동일한 이벤트가 저장 장치에 저장되었는지 여부를 확인하게하십시오. 그렇다면 그들은 그것을 처리하지 않아야합니다.

하지만 적절한 해결 방법을 찾지 않고 문제를 해결하려고하면 문제는 객체 A가 객체 B를들을 수 있고 객체 B가 객체 A를 동시에들을 수 있다는 것입니다 (어쩌면 중간 개체). 나쁜 디자인의 IMHO입니다.

관찰자는 느슨한 커플 링을 사용하여 객체 A가 객체 B에 대해 알게하고 반대는 반대가 아닙니다.

개체 A와 개체 B가 서로에 대해 알고 있다면 관찰자를 사용해야하는 이유가 표시되지 않습니다.

+0

도메인을 알지 못하는 항목은 없습니다. 나는 그래프를 구현하기 위해 접근법을 선호하지 않을 것이다. 즉, 클래스 그래프 을 생성하고 그것에 인접 매트릭스로 간단한 2 차원 배열을 가질 것이다. 이 방법을 사용하면 (적어도 나를 위해) 표준 그래프 알고리즘을 구현하는 것이 더 쉽습니다. – Roman

+0

어쩌면 당신은 무엇을 할 예정입니까? – Roman

+0

설명 할 수 없다면 어떻게 개발할 예정입니까? :)) – Roman

4

"이벤트"개체를 정의하는 경우 이벤트를 이미 처리 한 개체를 추가 할 수 있습니다. 이 경우 루프를 닫으면 종료 할 수 있습니다. *는 화재 뭔가 :이 경우 seudo 코드

eventFired(Event e) 
    if (e.hasBeenEvaluatedBy(this)){ 
    return; 
    } 
    e.addEvaluator(this); 

    // Do magic 

    refire(e); 
} 

에서 우리는 같은 것을 얻는다. * B는 *는의 재 소성 * B 잡는 그것을 처리하고리스트에 자신을 추가 은 * C 이벤트 처리 * B 형 재 소성을하고리스트에 자신을 추가 는 * A가 이벤트 처리 * C의 재 소성을하고리스트에 자신을 추가 이벤트이지만 이미 목록에 있습니다. 어떤 refire, 무한 루프는

을 파괴하지 대신 가비지 수집을 피하기 위해 포인터로 사용할 수

ID는 시스템이 단일 스레드 경우, 당신은 단순히 당신의 통지 방법 내부 경비를 필요

+0

이벤트 내에 방문한 노드 목록을 저장하는 것은 좋지 않은 생각입니다. 한 번 생성되는 일정한 수의 노드가 있습니다. 그리고 저장소 (즉, 목록 또는 집합)가 한 번 만들어집니다. 그러나 매 순간 많은 새로운 사건이 있습니다. 매 순간 새로운 목록이 많이 만들어 져야합니다. – Roman

6

발행 :

private boolean _notifying; 

public void notify() { 
    if(_notifying) { 
    return; 
    } 
    _notifying = true; 
    try { 
    // ... do notifying here... 
    } finally { 
    _notifying = false; 
    } 
} 
0

한 가지 방법은 무언가가 실제로 업데이트 된 경우 업데이트 된 이벤트 만 실행하는 것입니다. 이 방법의 장점은 트리거되는 이벤트 수를 줄이거 나 (작업 감소) 코드를 단순화 할 수 있다는 것입니다. 예 :

final Set<String> set = ... 

public void onAdded(String string) { 
    // is only added once. 
    if (set.add(string)) { 
     // only notifies once no matter how many times onAdded is 
     // called for this string, recursively or not. 
     notifyAdded(string); 
    } 
} 
+0

두 객체가 다른 객체의 변경 사항에 일치하려고 시도하지만 모순 된 방식으로 수행하면 실패 할 수 있습니다. 예를 들어, CheckBox1이 변경되면 CheckBox1과 일치하도록 상태가 변경되는 CheckBox2를 알립니다. CheckBox2가 변경되면 CheckBox1에 알리고 CheckBox1은 상태를 CheckBox2와 반대 방향으로 변경합니다. 둘 중 하나의 통지만으로도 좋지만, 함께 무한 루프 (무한 반복)를 강요합니다. – supercat

+0

상태 변경은 중요하지 않습니다. 이벤트 만이 이벤트를 한 번만 보급 할 수 있지만 그 자체로는 바람직하지 않을 수 있습니다. 그러나 한 번 이상 반복 할 수는 없습니다. –

관련 문제