문제

나는 양방향 협회를 다루는 일반적인 방법과 수동 서면 Java 코드의 역 업데이트를 처리하는 방법을 찾고 있습니다.

내가 무슨 말을하는지 모르는 사람들에게는 여기에 예가 있습니다. 아래는 (불만족스러운) 솔루션의 현재 결과입니다.

public class A {
    public B getB();
    public void setB(B b);
}

public class B {
    public List<A> getAs();
}

이제 협회의 끝을 업데이트 할 때 일관성을 유지하기 위해 다른 쪽 끝을 업데이트해야합니다. 매번 수동으로

a.setB(b);
b.getA().add(a);

또는 Setter / Getter에 일치하는 코드를 넣고 사용자 정의 목록 구현을 사용합니다.

더 이상 종속성을 사용할 수없는 구식, 인재되지 않은 프로젝트를 발견했습니다.https://e-nspire-gemini.dev.java.net/). 필요한 코드를 자동으로 주입하는 데 사용되는 주석을 사용하여 문제를 처리합니다.

Ala Gemini가 일반적이고 눈에 띄지 않는 방식으로 이것을 다루는 다른 프레임 워크를 아는 사람이 있습니까?

Ciao, Elmar

도움이 되었습니까?

해결책

Google 컬렉션 (Google의 내부 코드) - http://code.google.com/p/google-collection/ Java Generics 호환성 (호환 가능뿐만 아니라 제네릭을 잘 사용합니다)

클래스 BIMAP- http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/colbect/package-- Summary.html양방향 연관성을 허용합니다.

이 클래스 중 일부는 JDK 7로 향할 것으로 예상됩니다.

다른 팁

세터를 추상화하지 않으면 일종의 이벤트 알림 메커니즘을 제공해야합니다. 객체가 Javabeans 인 경우 PropertyChangesUpport를 사용하고 속성 변경 이벤트를 발사하는 것을보고 있습니다.

그렇게하는 경우 (또는 변경을 감지하기위한 다른 메커니즘이 있으면) 유리 목록은 ObservableElementList 이는 목록 끝에서 연관 동기화를 처리하는 데 쉽게 사용될 수 있습니다 (즉, A.Setb (b)를 자동으로 호출하는 a를 추가). 다른 방향은 속성 변경 모니터링 (또는 동등한)을 사용하여 쉽게 처리됩니다.

나는 이것이 일반적인 솔루션이 아니라는 것을 알고 있지만, 그것은 하나를위한 쉬운 기초가 될 것 같습니다.

이와 같은 것이 가능합니다 필요하다 B 클래스의 특별 목록 구현 - 일반적인 경우에 처리 할 수있는 AOP 유형 솔루션이 부족하지 않습니다 (즉, ArrayList 또는 이와 유사한 것을 사용).

또한 당신이 달성하려는 것은 데이터 구속력의 성배의 무언가라고 지적해야합니다. 필드 레벨에서 바인딩을위한 몇 가지 적절한 구현이 있습니다 (getters and setters와 같은 것들) (예제는 Jgoodies 바인딩 및 JSR 295 참조). 목록 유형 바인딩에 대한 정말 좋은 구현도 있습니다 (위에서 언급 한 유리 목록). 우리는 거의 모든 응용 프로그램에서 서로 협력하여 두 기술을 사용하지만, 당신이 요구하는 것만 큼 추상적으로 진행하려고 시도한 적이 없습니다.

내가 이것을 디자인한다면, 나는 다음과 같은 것을 보게 될 것입니다.

AssociationBuilder.createAssociation(A a, Connector< A> ca, B b,  Connector< B> cb, Synchronizer< A,B> sync)

커넥터는 다양한 변경 알림 유형에 대한 단일 인터페이스를 허용하는 인터페이스입니다. Synchronizer는 중 하나가 변경 될 때마다 두 객체 모두 동기화되도록 호출되는 인터페이스입니다.

sync(ChangeInfo info, A a, B b) // make sure that b reflects current state of a and vice-versa.  

ChangeInfo는 어떤 멤버 변경이 변경되었는지, 그리고 실제로 변경 사항이 있는지에 대한 데이터를 제공합니다. 우리는. 이 일반적인 것을 실제로 유지하려고한다면, 당신은 이것의 구현을 프레임 워크 사용자에게 펀트해야합니다.

위의 내용을 사용하면 다른 바인딩 기준을 충족하는 다수의 사전 정의 된 커넥터 및 동기화제가있을 수 있습니다.

흥미롭게도, 위의 방법 시그니처는 JSR 295 createeautobinding () 메소드 호출과 매우 유사합니다. 속성 객체는 커넥터와 같습니다. JSR 295는 동기화기가 없습니다 (대신, 열거로 지정된 바인딩 전략이 있습니다. Plus JSR 295는 속성> 속성 바인딩과 만 작동하여 한 객체의 필드 값을 해당 개체의 다른 개체 멤버십에 바인딩하려고합니다. 그들을 위해 테이블에도 없습니다).

이해하기 위해,이 calsses는 동료가 될 것입니다. 나는 일관성을 유지하기 위해 패키지-민간 메커니즘 (친구가없는 경우)을 제안합니다.

public final class A {
    private B b;
    public B getB() {
        return b;
    }
    public void setB(final B b) {
        if (b == this.b) {
            // Important!!
            return;
        }
        // Be a member of both Bs (hence check in getAs).
        if (b != null) {
            b.addA(this);
        }
        // Atomic commit to change.
        this.b = b;
        // Remove from old B.
        if (this.b != null) {
            this.b.removeA(this);
        }
    }
}

public final class B {
    private final List<A> as;
    /* pp */ void addA(A a) {
        if (a == null) {
            throw new NullPointerException();
        }
        // LinkedHashSet may be better under more demanding usage patterns.
        if (!as.contains(a)) {
            as.add(a);
        }
    }
    /* pp */ void removeA(A a) {
        if (a == null) {
            throw new NullPointerException();
        }
        as.removeA(a);
    }
    public List<A> getAs() {
        // Copy only those that really are associated with us.
        List<A> copy = new ArrayList<A>(as.size());
        for (A a : as) {
            if (a.getB() == this) {
                copy.add(a);
            }
        }
        return Collection.unmodifiableList(copy);
    }
}

(Disclaime : 테스트되지 않았거나 컴파일되지 않았습니다.)

대부분 예외 안전 (예외적으로 누출 될 수 있음). 스레드 안전, 많은 마니, 성능, 라이브러리 등은 관심있는 독자에게 연습으로 남아 있습니다.

모든 제안에 감사드립니다. 그러나 내가 찾고 있던 것에 가까운 사람은 아무도 없었으며, 아마도 질문을 잘못된 방식으로 공식화했을 것입니다.

나는 Gemini를 대체하기를 찾고 있었기 때문에 끝없는 점검과 특별 목록 구현으로 코드를 오염시키지 않으면 서 눈에 띄지 않는 방식으로이를 처리 할 수있는 방법을 찾고있었습니다. 이것은 Kevin이 제안한대로 AOP 기반 접근 방식을 요구합니다.

내가 조금 더 둘러 보았을 때 나는 CNET에서 모든 소스와 소스와 의존성을 포함하는 Gemini 패키지를 발견했습니다. 종속성의 누락 된 소스는 내가 그것을 사용하지 못하게 한 유일한 관심사였습니다. 이제 모든 소스를 사용할 수 있으므로 버그를 수정할 수 있습니다. 누구나 이것을 찾는 경우 : http://www.download.com/gemini/3000-2413_4-10440077.html

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top