컴포지트 패턴 또는 트리 구조를 사용할지 아니면 세 번째 구현을 사용할지 어떻게 알 수 있습니까?


14

" Observer "유형과 " Subject " 유형의 두 가지 클라이언트 유형이 있습니다 . 둘 다 그룹 계층 구조 와 관련 이 있습니다 .

관찰자는 서로 다른 계층 전체에서 연결된 그룹으로부터 데이터 를 받습니다 (달력) . 이 데이터는 데이터 를 수집하려는 그룹'부모'그룹데이터를 결합하여 계산됩니다 (각 그룹은 하나의 부모 만 가질 수 있음 ).

주체는 관련 그룹에서 데이터 (관찰자가받을)를 만들 수 있습니다. 그룹에서 데이터를 만들면 그룹의 모든 '자녀'도 데이터를 가지게되며 데이터 의 특정 영역에 대한 고유 한 버전 을 만들 수는 있지만 생성 된 원래 데이터 ( 특정 구현에서 원본 데이터에는 시간과 헤드 라인이 포함되며 하위 그룹은 해당 그룹에 직접 연결된 수신기의 나머지 데이터를 지정합니다.

그러나 주체가 데이터를 만들 때 영향을받는 모든 관찰자 에게이 데이터와 충돌 하는 데이터 가 있는지 확인해야합니다 . 이는 내가 이해할 수있는 한 큰 재귀 함수를 의미합니다.

그래서 나는 이것이 당신이 위아래로 갈 수있는 계층 구조 를 가질 수 있어야한다는 사실에 요약 될 수 있다고 생각 합니다. , 일부 장소 할 수 전체로 처리 (기본적으로, 재귀).

또한, 나는 작동하는 솔루션을 목표로하지 않습니다. 상대적으로 이해하기 쉽고 (적어도 아키텍처 측면에서는) 향후 추가 기능을 쉽게 수신 할 수있을 정도로 유연한 솔루션을 찾고 싶습니다.

이 문제 또는 유사한 계층 구조 문제를 해결하기위한 디자인 패턴이나 모범 사례가 있습니까?

편집하다 :

내가 가진 디자인은 다음과 같습니다. 메소드가 포함 된 클래스 다이어그램.  "그룹"클래스는 계층입니다

"Phoenix"클래스는 적절한 이름을 아직 생각하지 않았기 때문에 그렇게 명명되었습니다.

그러나 이것 이외에도 특정 관찰자 들이 그룹을 통해 그들에게 붙어 있음에도 불구하고 특정 관찰자들에 대한 특정 활동 들을 숨길 수 있어야합니다 .


약간의 주 제외 :

개인적으로, 나는이 문제를 더 작은 문제로 잘라낼 수 있어야한다고 생각하지만 어떻게 나아갈 수 없습니다. 서로 관련이없는 여러 재귀 기능과 다른 방식으로 정보를 가져와야하는 다른 클라이언트 유형이 관련되어 있기 때문이라고 생각합니다. 나는 정말로 머리를 감쌀 수 없다. 누군가가 계층 구조 문제를 캡슐화하는 데 더 나은 방법을 안내 할 수 있다면 그 사실을 매우 기쁘게 생각합니다.


이것은 그래프 이론 문제처럼 들립니다. 그래서 우리는 그룹의 계층 구조를 나타내는 몇 개의 그래프가 있습니다. 각 그룹은 그래프의 꼭짓점입니다. 어떤 속성이 사실입니까? n다른 모든 정점이 최소 1 이상의 정도를 갖는 반면 항상 0 도의 고유 한 정점이 존재한다는 것이 사실 입니까? 모든 정점이 연결되어 n있습니까? n독창적 인 길인가 ? 데이터 구조의 속성을 나열하고 그 동작을 인터페이스 (메소드 목록)로 추상화 할 수 있다면, 우리는 (I) 상기 데이터 구조의 구현을 생각 해낼 수있을 것입니다.

당신의 응답을 주셔서 감사합니다. Observers를 제외하고는 서로 연결되지 않은 여러 계층의 그룹이 있지만 그래프 객체의 일부라고 생각하지 않으며 단지 정점에 대한 링크가 있다고 생각합니다. 계층의 각 그룹은 부모를 1 명만 가질 수 있지만 자식은 0 .. *입니다. 그래프로 어떻게 구현 하시겠습니까? 그룹이 1 개인 계층 만 0의 차수를 갖습니다. 2 그룹 계층 이상의 경우 모두 1 이상의 동위 및 외도를 갖습니다. 관련 방법을 나열 해 보겠습니다. 내가 직장에있을 때 한 시간 안에

따라서 그룹은 C #에서 서브 클래 싱처럼 작동합니까? 포리스트 (예 : 분리 된 트리)가있는 경우를 제외하고 하나의 기본 클래스를 서브 클래 싱 할 수 있습니까? 모든 포인터 / 참조를 연결하면 암시 적으로 이미 그래프가 있습니다. 다른 작업을 수행 할 필요가 없습니다. 그러나 "이 두 그룹이 같은 계층 구조에 있습니까?"와 같은 작업을 효율적으로 수행하려는 경우가 있습니다. "이 두 그룹의 공통 조상은 무엇입니까?" 등 당신은 당신이 구조에 대해 미리 알고있는 모든 것을 이용하기 위해 체계적으로 분석 된 문제가 필요합니다.

이제 다이어그램을 보았으므로 귀하의 질문은 정확히 무엇입니까? 디자인 접근 방식에 관한 것이라면 다양한 디자인 방법론을 처음 접했기 때문에이 시점에서 실제로 당신을 도울 수 없습니다. 그러나 O(n)잘 정의 된 데이터 구조에 대한 효율적인 알고리즘을 찾고 있다면 그 일을 할 수 있습니다. Group계층 구조의 변경 방법 과 구조를 넣지 않은 것으로 보입니다 . 이것이 정적이라고 가정합니까?

1
@ Malachi 나는 대답을 찾지 못했습니다. 불행히도 나는 그것을 완전히 조사 할 시간이 없었고 다른 것으로 옮겨야했습니다. 지금도 살펴볼 시간이 없지만 때때로 알림을 한 번에 한 번씩 확인해야합니다. 누군가가 훌륭한 답변을한다면 받아들이겠습니다.
Aske B.

답변:


1

다음은 루트로 이동하고 해당 루트의 트리를 모음으로 탐색 할 수있는 간단한 "그룹"구현입니다.

public class Group
{
  public Group Parent
  public List<Group> Children

  public IEnumerable<Group> Parents()
  {
    Group result = this;
    while (result.Parent != null)
    {
      result = result.Parent;
      yield return result;
    }
  }
  public Group Root()
  {
    return Parents.LastOrDefault() ?? this;
  }


  public IEnumerable<Group> WalkTreeBreadthFirst(
  {
    //http://en.wikipedia.org/wiki/Breadth-first_search
    HashSet<Group> seenIt = new HashSet<Group>()
    Queue<Group> toVisit = new Queue<Group>();
    toVisit.Enqueue(this);

    while (toVisit.Any())
    {
      Group item = toVisit.Dequeue();
      if (!seenIt.Contains(item))
      {
        seenIt.Add(item);
        foreach (Group child in item.Children)
        {
          toVisit.Enqueue(child);
        }
        yield return item;
      }
    }
  }

  public static IEnumerable<Group> WalkTreeDepthFirst()
  {
    // http://en.wikipedia.org/wiki/Depth-first_search
    HashSet<Group> seenIt = new HashSet<Group>();
    Stack<Group> toVisit = new Stack<Group>();

    toVisit.Push(this);

    while (toVisit.Any())
    {
      Group item = toVisit.Pop();
      if (!seenIt.Contains(item))
      {
        seenIt.Add(item);
        foreach (Group child in item.Children.Reverse())
        {
          toVisit.Push(child);
        }
        yield return item;
      }
    }
  }
}

따라서 그룹이 주어지면 해당 그룹의 트리를 걷을 수 있습니다.

Group myGroup = GetGroup();
Group root = myGroup.Root;
foreach(Group inTree in root.WalkTreeBreadthFirst())
{
  //do something with inTree Group.
}

이 글을 게시하려는 희망은 트리를 탐색하는 방법과 그 복잡성을 없애는 방법을 보여줌으로써 트리에서 수행하려는 작업을 시각화 한 다음 패턴을 직접 방문하여 볼 수 있다는 것입니다 가장 적합한 것은 무엇입니까?


0

제한된보기로 인해 시스템의 사용 또는 구현 요구 사항에 대해 너무 구체적으로 설명하기는 어렵습니다. 예를 들어, 고려할 사항은 다음과 같습니다.

  • 시스템이 많은 동시 사용자입니까 (많은 사용자)?
  • 데이터 액세스의 읽기 / 쓰기 비율은 얼마입니까? (높은 읽기, 낮은 쓰기가 일반적 임)

패턴 등에 관해서는 솔루션에서 정확한 패턴이 자르는 것에 대해 덜 걱정하고 실제 솔루션의 디자인에 대해 더 걱정합니다. 필자는 디자인 패턴에 대한 지식이 유용하지만 전부가 아니라 전체가 아니라고 생각한다. 작가 비유를 사용하기 위해 디자인 패턴은 문장의 사전이 아니라 일반적으로 보이는 문구의 사전과 비슷하다. 에서.

당신의 다이어그램은 일반적으로 나에게 좋아 보인다.

언급하지 않은 메커니즘이 있으며 계층 구조에 일종의 캐시 가 있습니다. 분명히 이것을 신중하게 구현해야하지만 시스템 성능을 크게 향상시킬 수 있습니다. 다음은 간단한 설명입니다 (캐비티 emptor).

계층의 각 노드에 대해 상속 된 데이터를 노드와 함께 저장하십시오. 게 으르거나 능동적으로 행동하십시오, 그것은 당신에게 달려 있습니다. 업데이트가 계층 구조를 만들 때 다음 중 하나가 다음 영향을받는 모든 노드의 캐시 데이터를 재생성 할 수 있습니다 또는 적절한 장소에서 세트 '더러운'플래그, 필요한 경우 발생하는 재 유유히 영향을받는 데이터를 가지고있다.

나는 이것이 당신의 시스템에 얼마나 적합한 지 잘 모르지만 고려해 볼 가치가 있습니다.

또한 SO에 대한이 질문은 관련이있을 수 있습니다.

/programming/1567935/how-to-do-inheritance-modeling-in-relational-databases


0

나는 이것이 명백한 종류라는 것을 알고 있지만 어쨌든 말할 것입니다 Observer Pattern . 관찰자 유형이 있고 당신이 나에게 관찰자 패턴과 비슷한 것을 언급 한 것을 보아야한다고 생각합니다 .

몇 개의 링크 :

DoFactory

oodesign

그것들을 확인하십시오. 그렇지 않으면 다이어그램에있는 것을 코딩 한 다음 디자인 패턴을 사용하여 필요한 경우 단순화합니다. 당신은 이미 무엇이 일어나고 프로그램이 어떻게 작동해야하는지 알고 있습니다. 코드를 작성하고 여전히 적합한 지 확인하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.