Kompozit Desen mi yoksa Ağaç Yapısı mı yoksa üçüncü bir uygulama mı kullanılacağını nasıl anlarsınız?


14

İki istemci tipim var, " Gözlemci " tipi ve " Konu " tipi. İkisi de grup hiyerarşisiyle ilişkilidir .

Gözlemci , farklı hiyerarşiler boyunca ilişkili olduğu gruplardan veri (takvim) alır . Bu veriler, veri toplamaya çalışan grubun 'üst' gruplarından gelen veriler birleştirilerek hesaplanır (her grubun yalnızca bir üst öğesi olabilir ).

Konu, ilişkili oldukları gruplarda verileri (Gözlemcilerin alacağı) oluşturabilir. Bir grupta veri oluşturulduğunda, grubun tüm 'alt öğeleri' de verilere sahip olacak ve verilerin belirli bir alanının kendi sürümlerini oluşturabilecek , ancak yine de oluşturulan orijinal verilere bağlanabilecek ( benim özel uygulama, orijinal veriler zaman periyotları ve başlık içerirken, alt gruplar doğrudan ilgili gruplarına bağlı alıcılar için geri kalan verileri belirtir).

Ancak, Konu veri oluşturduğunda, etkilenen tüm Gözlemcilerin bununla çelişen herhangi bir veri olup olmadığını kontrol etmesi gerekir , bu da anlayabildiğim kadarıyla büyük bir özyinelemeli işlev anlamına gelir.

Bu yüzden, bu, yukarı ve aşağı gidebileceğiniz bir hiyerarşiye sahip olmam gerektiğini ve bazı yerlerde onları bir bütün olarak ele alabileceğim gerçeğiyle özetlenebilir (özyineleme, temelde).

Ayrıca, sadece işe yarayan bir çözüm hedeflemiyorum. Anlamak nispeten kolay bir çözüm bulmayı umuyorum (en azından mimari olarak) ve ayrıca gelecekte ek işlevsellik alabilecek kadar esnek.

Bu problemi veya benzer hiyerarşi problemlerini çözmek için bir tasarım deseni veya iyi bir uygulama var mı?

DÜZENLE :

İşte sahip olduğum tasarım: Yöntemlerle sınıf diyagramı.  "Grup" sınıfı hiyerarşidir

"Phoenix" sınıfı bu şekilde adlandırıldı çünkü henüz uygun bir isim düşünmedim.

Ancak bunun yanında , gruplar aracılığıyla kendilerine bağlı olmalarına rağmen, belirli gözlemciler için belirli etkinlikleri gizleyebilmem gerekiyor .


Biraz konu dışı :

Şahsen, bu problemi daha küçük problemlere parçalayabilmem gerektiğini hissediyorum, ama bu bana nasıl kaçıyor. Bence, birbirleriyle ilişkili olmayan çoklu özyinelemeli işlevsellikler ve farklı şekillerde bilgi alması gereken farklı istemci türleri içerdiğini düşünüyorum. Kafamı gerçekten saramıyorum. Birisi bana hiyerarşi problemlerini kapsülleme konusunda nasıl daha iyi olabileceğim konusunda rehberlik edebilirse, bunu da almaktan çok memnun olurum.


Bu bir grafik teorisi problemi gibi geliyor. Yani grupların hiyerarşisini temsil eden bir digrafimiz var. Her grup, grafikteki bir tepe noktasıdır. Hangi özellikler geçerli? Her zaman nbaşka bir tepe noktasının en az 1 derece olduğu benzersiz bir tepe noktası olduğu doğru mu? Her tepe noktası bağlı mı n? Yol nbenzersiz mi? Veri yapısının özelliklerini listeleyebilir ve işlemlerini bir arayüze soyutlayabilirseniz - bir yöntem listesi - biz (I) söz konusu veri yapısının bir uygulamasını yapabiliriz.

Cevabınız için teşekkürler. Gözlemciler dışında birbirine bağlı olmayan birden fazla grup hiyerarşisi vardır, ancak grafik nesnelerinin bir parçası olduklarını düşünmüyorum, sadece içlerindeki köşelere bir bağlantıları var. Bir hiyerarşideki her grubun yalnızca 1 üst öğesi olabilir, ancak 0 .. * alt öğesi olabilir. Bunu bir grafikte nasıl uygularsınız? Ve sadece 1 gruplu bir hiyerarşi 0 dereceye sahip olacaktır. 2-grup hiyerarşisi ve daha büyükleri için hepsi en az 1 eşit giriş ve çıkış derecesine sahip olacaktır. bir saat içinde, işteyken.

Peki gruplar C # alt sınıflama gibi çalışır: Bir orman (yani ayrık ağaçlar) hariç, bir temel sınıf alt sınıf olabilir? Tüm işaretçileri / referansları bağlarsanız, dolaylı olarak bir grafiğiniz vardır, başka bir şey yapmanıza gerek yoktur. Yine de, "Bu iki grup aynı hiyerarşide mi?" "Bu iki grubun ortak atası nedir?" vb. yapı hakkında önceden bildiğiniz her şeyden faydalanmak için sistematik olarak analiz edilen soruna ihtiyacınız vardır.

Şimdi şemanızı gördüğüme göre, sorunuz tam olarak nedir - eğer tasarım yaklaşımı ile ilgiliyse, bu noktada size gerçekten yardımcı olamıyorum çünkü çeşitli tasarım yöntemlerinde yeniyim, kendim. Ancak, O(n)iyi tanımlanmış bir veri yapısı için verimli algoritmalar arıyorsanız , bunun üzerinde çalışabilirim. GroupHiyerarşilerin yapısını ve yapısını herhangi bir mutasyona uğratma yöntemi kullanmadığınızı görüyorum . Bunların durağan olacağını varsaymalı mıyım?

1
@Malachi Bir cevap bulamadım. Ne yazık ki tam olarak araştırmak için zamanım yoktu ve başka bir şeye geçmek zorunda kaldım. Şimdi de bu konuya bakacak zamanım yok, ancak bildirimlerimi arada bir kontrol ettiğimden emin olacağım - ve birisi iyi bir cevap verirse, kabul edeceğim.
Aske B.22

Yanıtlar:


1

Kök'e gitmenizi ve bu Kök'ün ağacında koleksiyon olarak gezinmenizi sağlayan basit bir "Grup" uygulaması.

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;
      }
    }
  }
}

Yani - bir grup verildiğinde, o Grubun ağacında yürüyebilirsiniz:

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

Bunu yayınlama umudum, bir ağaçta nasıl gezinileceğini (ve karmaşıklığını ortadan kaldırarak) göstererek, ağaç üzerinde gerçekleştirmek istediğiniz işlemleri görselleştirebilir ve daha sonra desenleri görmek için kendi başınıza tekrar ziyaret edebilirsiniz. en iyi olanı.


0

Sisteminizin kullanım veya uygulama gerekliliklerine ilişkin sınırlı görüşümüz sayesinde, çok spesifik olmak zordur. Örneğin, dikkate alınacak şeyler şunlar olabilir:

  • sistem oldukça eşzamanlı mı (çok sayıda kullanıcı)?
  • veri erişiminin okuma / yazma oranı nedir? (yüksek okuma, düşük yazma yaygındır)

Desenler vb. Gelince, çözümünüzde hangi kesin desenlerin ortaya çıktığı ve asıl çözümün tasarımı hakkında daha az endişelenirim. Tasarım desenleri bilgisinin yararlı olduğunu düşünüyorum, ancak hepsi ve hepsi değil: bir yazar benzetmesi kullanmak için, tasarım desenleri yaygın olarak görülen ifadelerin sözlüğü gibidir, bir cümle sözlüğü yerine bir kitabın tamamını yazmalısınız dan.

Diyagramınız genellikle bana iyi geliyor.

Bahsetmediğiniz bir mekanizma vardır ve bu hiyerarşinizde bir tür önbellek bulundurmaktır. Açıkçası bunu büyük bir dikkatle uygulamalısınız, ancak sisteminizin performansını önemli ölçüde artırabilir. İşte basit bir bakış (uyarı emptor):

Hiyerarşinizdeki her düğüm için devralınan verileri düğümle birlikte depolayın. Bunu tembel veya proaktif olarak yapın, bu size kalmış. Bir güncelleştirme hiyerarşi yapıldığında, etkilenen tüm düğümler için önbellek verilerini yeniden oluşturabilir veya ardından uygun yerlerde 'kirli' bayraklar ayarlayabilir ve etkilenen verilerin gerektiğinde tembel bir şekilde yeniden oluşturulmasını sağlayabilirsiniz.

Bunun sisteminizde ne kadar uygun olduğu hakkında hiçbir fikrim yok, ama dikkate değer olabilir.

Ayrıca, SO ile ilgili bu soru ilgili olabilir:

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


0

Bunun Açıkçası olduğunu biliyorum ama yine de söyleyeceğim Observer Pattern , bir Gözlemci Tipiniz olduğundan ve sahip olduğunuz şeyin bana Gözlemci Deseni gibi gözüktüğünüzü düşünüyorum.

birkaç bağlantı:

DoFactory

oodesign

kontrol edin. Aksi takdirde sadece Diyagramınızdaki kodları kodlar ve sonra gerekirse Tasarım Desenini kullanırdım. ne olması gerektiğini ve programın nasıl çalışması gerektiğini zaten biliyorsunuz. Bazı Kodlar yazın ve hala uygun olup olmadığını görün.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.