2012-01-29 3 views
1

MVVM 패턴을 사용하는 WPF 응용 프로그램의 모델 인 개체 계층 구조가 있습니다. 하위 개체는 계층 구조의 루트 개체에 설정된 속성을 알고 있어야합니다. 이 속성은 때때로 변경 될 수 있습니다 (계층이 만들어 질 때 설정되는 것이 아닙니다). 이 요구 사항이 떠오르 기 전에, 아이가 부모 또는 루트 객체에 대한 참조를 가질 이유가 없었습니다.MVVM 모델 계층 구조의 값 공유

간체, 단축 예 :

A) 아이들에게 부모 (또는 루트) 객체 참조를 추가

public class Airplane 
    public bool IsFlying { get; set} 
    public ObservableCollection<WingAssembly> WingAssemblies { get; set; } 

public class WingAssembly 
    public void MethodNeedsIsFlyingState() { } 
    public Flaps Flaps { get; set; } 

public class Flaps 
    public void MethodAlsoNeedsIsFlyingState() { } 

두 패턴이 문제를 해결하기 위해 나에게 발생합니다.

PRO의 : 간단한 변화,

CON의 루트 객체의 상태를 참조 할 간단 : 나는으로 실행할 수 있습니다 다운 스트림 어떤 결과가 확실하지 않다 ... 이전에 필요하지 않은 양방향 객체 계층 구조를 작성합니다 (더 복잡한 데이터 모델?)

B) IsFlying 속성을 필요로하는 하위 개체에 추가하십시오. 루트의 상태가 변경되면 하위 노드의 상태를 업데이트합니다.

PRO : 객체 계층 구조는 여전히 하위가 parent/root를 알 필요가 없습니다.

조건부 : 모델이 발전하면서 필요한 업데이트를 놓치기 쉽습니다. 어린이 IsFlying 상태는 루트 객체 이외의 다른 사용자가 변경할 수 있습니다. 더 복잡한.

내 기댈 것은 모든 자손의 루트에 대한 참조를 소개하는 것입니다. 그러나 더 우아한 해결책을 놓치고 있는지, 또는 그 경로의 중요한 결과를 놓치거나 과소 평가했는지 알고 싶습니다.

답변

1

첫 번째 제안보다 더 간단한 것이 없을 것이라고 생각합니다.

두 번째는 잠재적 인 버그를 노출하고 다른 솔루션은 날개를 비행기에 연결하는 추가 클래스가 필요합니다.

첫 번째로 이동하고 나중에 모델이 너무 복잡해지면 추가 개체로 나누십시오. 이제는 걱정할 필요가 없습니다.

0

나를 위해 잘 작동 한 한 패턴은 단순화 된 컨테이너 모델입니다. 간단히 구성 요소에 대한 간단한 호모 모르 픽 인터페이스 정의 넣어 : 당신은이 같은 확장 방법을 쓸 수

public interface IContained 
{ 
    IContained Parent { get; set; } 
}  

을 특정 부모의 계층 구조의 모든 수준으로 이동 :

public IContained GetContainer(this IContained ChildObject) 
{ 
    if (ChildObject == null) { 
     return null; 
    } 

    return ChildObject.Parent; 
} 

public T GetContainer<T>(this IContained ChildObject) 
{ 
    if (ChildObject == null) 
     return null; 

    ChildObject = ChildObject.Parent; 

    while (ChildObject != null && !ChildObject is T) { 
     ChildObject = ChildObject.Parent; 
    } 

    return (T)ChildObject; 
} 

것은 아래로 이동하려면 , 다른 간단한 인터페이스를 정의 할 수 있습니다 :

public interface IContainedComponent 
{ 
    IEnumerable<IContainedComponent> GetComponents(); 
} 

트릭은 기본 클래스와 유유히 당신을 위해 부모의 속성을 설정 컬렉션을 만드는입니다, 또는 열거 자식 개체. 상당히 유연한 패턴입니다.

+0

를 업데이트 부모에하여 PropertyChanged 이벤트를 추가 할 수 있지만 내가 사용할 수있는 옵션 중 하나를 선택 도움이되지 않습니다 . 그래도 입력 주셔서 감사합니다. –

0

옵션 "A"는 "Loose coupling"에 반대하며 소프트웨어 아키텍처에서 가장 중요한 원칙입니다.

자녀는 최소한 인터페이스를 구현하거나 부모를 악화시켜야합니다. 즉, 자녀 코드가 상위 코드에 묶여 있음을 의미합니다.

또한 MVVM에서 부모를 아는 것이 INotifyPropertyChanged 이벤트가 자동으로 자녀에게 발생한다는 것을 의미하지는 않습니다. 요구 사항 인 경우 아이에게 IsFlying 속성이 필요함을 의미합니다. 그것이 요구 사항이 아니라면 미래에 하나가 될 것인가?

느슨한 커플 링 경로에 머무르는 다른 옵션이있을 수 있습니다. 부모가 설정 한 자식에 anonomous 대리자 또는 func이 있고 부모 IsFlying 속성을 반환합니다.

또는 아이들을 인스턴스화 할 때, 아이 예를 우아하게 구현 옵션 A에 대한 가능한 메커니즘의

public class Airplane 
{ 
    WingAssembly _wing; 

    protected void CreateWing() 
    { 
     wing = new WingAssembly(); 
     PropertyChanged += (s,e) => wing.IsFlying = IsFlying; 
    } 
} 
관련 문제