Bagaimana Anda bisa tahu apakah akan menggunakan Pola Komposit atau Struktur Pohon, atau implementasi ketiga?

14

Saya memiliki dua jenis klien, tipe " Observer " dan " Subjek ". Keduanya terkait dengan hierarki grup .

Pengamat akan menerima data (kalender) dari grup yang dikaitkan dengan seluruh hierarki yang berbeda. Data ini dihitung dengan menggabungkan data dari kelompok 'induk' dari kelompok yang mencoba mengumpulkan data (setiap kelompok hanya dapat memiliki satu induk ).

Subjek akan dapat membuat data (yang akan diterima Pengamat) dalam grup yang terkait dengannya. Ketika data dibuat dalam suatu grup, semua 'anak' dari grup akan memiliki data juga, dan mereka akan dapat membuat versi mereka sendiri dari area spesifik dari data , tetapi masih tertaut dengan data asli yang dibuat (dalam implementasi spesifik saya, data asli akan berisi periode waktu dan informasi utama, sementara subkelompok menentukan sisa data untuk penerima yang terhubung langsung ke grup masing-masing).

Namun, ketika Subjek membuat data, ia harus memeriksa apakah semua Pengamat yang terpengaruh memiliki data yang bertentangan dengan ini, yang berarti fungsi rekursif besar, sejauh yang saya bisa mengerti.

Jadi saya pikir ini dapat disimpulkan dengan fakta bahwa saya harus dapat memiliki hierarki yang dapat Anda naik turun , dan beberapa tempat dapat memperlakukan mereka secara keseluruhan (rekursi, pada dasarnya).

Juga, saya tidak hanya mengincar solusi yang berhasil. Saya berharap menemukan solusi yang relatif mudah dipahami (setidaknya berdasarkan arsitektur) dan juga cukup fleksibel untuk dapat dengan mudah menerima fungsionalitas tambahan di masa depan.

Apakah ada pola desain, atau praktik yang baik untuk dilakukan, untuk menyelesaikan masalah ini atau masalah hierarki serupa?

EDIT :

Inilah desain yang saya miliki: Diagram kelas dengan metode yang disertakan.  Kelas "Grup" adalah hierarki

Kelas "Phoenix" dinamai demikian karena saya belum memikirkan nama yang tepat.

Tapi selain itu saya harus bisa menyembunyikan kegiatan khusus untuk pengamat tertentu , meskipun mereka melekat padanya melalui kelompok.


Sedikit di luar topik :

Secara pribadi, saya merasa bahwa saya harus bisa memotong masalah ini menjadi masalah yang lebih kecil, tetapi saya tidak tahu caranya. Saya pikir itu karena itu melibatkan beberapa fungsi rekursif yang tidak terkait satu sama lain dan jenis klien yang berbeda yang perlu mendapatkan informasi dengan cara yang berbeda. Aku tidak bisa benar-benar membungkus kepalaku. Jika ada yang bisa membimbing saya ke arah bagaimana menjadi lebih baik dalam merangkum masalah hierarki, saya akan sangat senang menerima itu juga.

Aske B.
sumber
Ini terdengar seperti masalah teori grafik. Jadi kami memiliki beberapa digraf yang mewakili hierarki kelompok. Setiap grup adalah simpul dalam grafik. Properti apa yang benar? Apakah benar bahwa selalu ada simpul unik ndengan derajat 0 sedangkan setiap simpul lainnya memiliki derajat minimal 1? Apakah setiap titik terhubung n? Apakah jalan menuju nkeunikan? Jika Anda bisa membuat daftar properti dari struktur data dan abstrak operasinya ke antarmuka - daftar metode - kami (saya) mungkin dapat membuat implementasi dari struktur data tersebut.
Terima kasih atas tanggapan Anda. Ada beberapa hierarki grup yang tidak saling menempel, kecuali melalui Pengamat, tetapi saya tidak berpikir mereka adalah bagian dari objek grafik, mereka hanya memiliki tautan ke simpul di dalamnya. Setiap grup dalam hierarki hanya dapat memiliki 1 orang tua, tetapi 0 .. * anak-anak. Bagaimana Anda menerapkannya dalam grafik? Dan hanya hierarki dengan 1 grup yang akan memiliki derajat 0. Untuk 2 hierarki grup dan lebih besar mereka semua akan memiliki derajat masuk dan keluar minimal sama dengan 1. Saya akan mencoba daftar metode yang relevan dalam satu jam, ketika saya sedang bekerja.
Jadi, apakah kelompok bekerja seperti subklas pada C #: Anda dapat subkelas satu kelas dasar, dengan pengecualian bahwa ada hutan (yaitu pohon terpisah)? Nah jika Anda menghubungkan semua pointer / referensi maka secara implisit Anda memiliki grafik, sudah - Anda tidak perlu melakukan hal lain. Masalahnya, jika Anda ingin melakukan operasi secara efisien seperti "Apakah kedua grup ini berada dalam hierarki yang sama?" "Apa nenek moyang yang sama untuk dua kelompok ini?" dll. Anda perlu masalah yang dianalisis secara sistematis untuk mengambil keuntungan dari semua hal yang Anda ketahui sebelumnya tentang struktur.
Sekarang saya telah melihat diagram Anda, apa pertanyaan Anda sebenarnya - jika ini tentang pendekatan desain saya tidak dapat benar-benar membantu Anda pada saat ini karena saya baru mengenal berbagai metodologi desain, saya sendiri. Namun jika Anda mencari O(n)algoritma yang efisien untuk struktur data yang terdefinisi dengan baik, saya dapat mengatasinya. Saya melihat Anda tidak menggunakan metode mutasi apa pun Groupdan struktur hierarki. Apakah saya berasumsi bahwa ini akan menjadi statis?
1
@Malachi saya tidak menemukan jawaban. Sayangnya saya tidak punya waktu untuk menyelidiki sepenuhnya dan harus pindah ke sesuatu yang lain. Saya juga tidak punya waktu untuk memeriksanya, tetapi saya akan memastikan untuk memeriksa notifikasi saya sesekali - dan jika seseorang membuat jawaban yang bagus, maka saya akan menerimanya.
Aske B.

Jawaban:

1

Inilah implementasi "Grup" sederhana yang memungkinkan Anda menavigasi ke Root, dan menavigasi pohon Root sebagai koleksi.

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

Jadi - dengan diberikan grup, Anda dapat berjalan di pohon Grup itu:

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

Harapan saya dalam memposting ini, adalah bahwa dengan menunjukkan cara menavigasi pohon (dan menghilangkan kerumitannya), Anda mungkin dapat memvisualisasikan tentang operasi yang ingin Anda lakukan di pohon, dan kemudian meninjau kembali pola Anda sendiri untuk melihat apa yang terbaik berlaku.

Amy B
sumber
0

Dengan tampilan terbatas yang kami miliki tentang persyaratan penggunaan atau implementasi sistem Anda, sulit untuk menjadi terlalu spesifik. Misalnya, hal-hal yang akan dipertimbangkan mungkin:

  • Apakah sistem ini sangat bersamaan (banyak pengguna)?
  • apa rasio baca / tulis dari akses data? (baca tinggi, tulis rendah biasa)

Mengenai pola, dll., Saya tidak akan terlalu khawatir tentang pola pasti apa yang muncul dalam solusi Anda, dan lebih banyak tentang desain solusi aktual. Saya pikir pengetahuan tentang pola desain berguna, tetapi tidak semua-dan-semua: untuk menggunakan analogi penulis, pola desain lebih seperti kamus frasa yang umum dilihat, daripada kamus kalimat Anda harus menulis seluruh buku dari.

Diagram Anda secara umum terlihat ok untuk saya.

Ada satu mekanisme yang belum Anda sebutkan dan itu adalah memiliki semacam cache dalam hierarki Anda. Jelas Anda harus menerapkan ini dengan sangat hati-hati, tetapi ini dapat secara signifikan meningkatkan kinerja sistem Anda. Berikut ini adalah contoh sederhana (peringatan peringatan):

Untuk setiap node dalam hierarki Anda, simpan data yang diwarisi dengan node tersebut. Lakukan ini dengan malas atau pro-aktif, itu terserah Anda. Saat pembaruan dibuat hierarki, Anda dapat membuat ulang data cache untuk semua node yang terpengaruh di sana dan kemudian, atau mengatur bendera 'kotor' di tempat yang sesuai, dan membuat data yang terpengaruh dihasilkan kembali dengan malas ketika diperlukan.

Saya tidak tahu seberapa tepat ini dalam sistem Anda, tetapi mungkin patut dipertimbangkan.

Juga, pertanyaan tentang SO ini mungkin relevan:

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

occulus
sumber
0

Saya tahu ini Jenis Obvious tetapi saya akan mengatakannya, saya pikir Anda harus melihat pada yang Observer Pattern Anda sebutkan bahwa Anda memiliki Jenis Pengamat dan apa yang Anda miliki terlihat seperti Pola Pengamat bagi saya.

beberapa tautan:

DoFactory

oodesign

lihat itu. kalau tidak, saya hanya akan Kode apa yang Anda miliki di Diagram Anda dan kemudian menggunakan Pola Desain untuk menyederhanakan jika perlu. Anda sudah tahu apa yang perlu terjadi dan bagaimana program seharusnya bekerja. Tulis beberapa Kode dan lihat apakah masih cocok.

Maleakhi
sumber