คุณจะบอกได้อย่างไรว่าจะใช้รูปแบบคอมโพสิตหรือโครงสร้างแบบต้นไม้หรือการนำไปใช้ครั้งที่สาม


14

ฉันมีสองประเภทลูกค้า "ผู้สังเกตการณ์ " - ประเภทและ " Subject " -type ทั้งคู่เกี่ยวข้องกับลำดับชั้นของกลุ่มลำดับชั้นของกลุ่ม

ผู้สังเกตการณ์จะได้รับ(ปฏิทิน) ข้อมูลจากกลุ่มที่เกี่ยวข้องกับตลอดทั้งลำดับชั้นที่แตกต่างกัน ข้อมูลนี้ถูกคำนวณโดยการรวมข้อมูลจากกลุ่ม 'ผู้ปกครอง'ของกลุ่มที่พยายามรวบรวมข้อมูล (แต่ละกลุ่มสามารถมีผู้ปกครองได้เพียงคนเดียว )

หัวเรื่องจะสามารถสร้างข้อมูล (ซึ่งผู้สังเกตการณ์จะได้รับ) ในกลุ่มที่พวกเขาเชื่อมโยงด้วย เมื่อข้อมูลถูกสร้างขึ้นในกลุ่ม 'ลูก' ของกลุ่มทั้งหมดจะมีข้อมูลเช่นกันและพวกเขาจะสามารถสร้างพื้นที่เฉพาะของข้อมูลในเวอร์ชันที่เป็นของตัวเองแต่ยังคงเชื่อมโยงกับข้อมูลดั้งเดิมที่สร้างขึ้น (ใน การใช้งานเฉพาะของฉันข้อมูลดั้งเดิมจะมีช่วงเวลาและพาดหัวในขณะที่กลุ่มย่อยระบุข้อมูลที่เหลือสำหรับผู้รับที่เชื่อมโยงโดยตรงกับกลุ่มของตน)

อย่างไรก็ตามเมื่อหัวเรื่องสร้างข้อมูลจะต้องตรวจสอบว่าผู้สังเกตการณ์ที่ได้รับผลกระทบทั้งหมดมีหรือไม่ ข้อมูลที่ขัดแย้งกับสิ่งนี้หรือไม่ซึ่งหมายถึงฟังก์ชั่นวนซ้ำขนาดใหญ่เท่าที่ฉันสามารถเข้าใจได้

ดังนั้นฉันคิดว่าสิ่งนี้สามารถสรุปได้ถึงความจริงที่ว่าฉันต้องมีลำดับชั้นที่คุณสามารถขึ้นและลงและบางแห่งสามารถปฏิบัติต่อพวกเขาโดยรวมได้ (การเรียกซ้ำโดยทั่วไป)

นอกจากนี้ฉันไม่ได้แค่มุ่งแก้ปัญหาที่ใช้งานได้ ฉันหวังว่าจะหาวิธีแก้ปัญหาที่ค่อนข้างง่ายต่อการเข้าใจ (อย่างน้อยต้องมีสถาปัตยกรรมอย่างชาญฉลาด) และยังมีความยืดหยุ่นเพียงพอที่จะรับฟังก์ชั่นเพิ่มเติมในอนาคตได้อย่างง่ายดาย

มีรูปแบบการออกแบบหรือแนวปฏิบัติที่ดีในการแก้ปัญหานี้หรือปัญหาลำดับชั้นที่คล้ายกัน

แก้ไข :

นี่คือการออกแบบของฉัน: แผนภาพระดับพร้อมวิธีการรวม  คลาส "กลุ่ม" เป็นลำดับชั้น

คลาส "Phoenix" ตั้งชื่ออย่างนั้นเพราะฉันยังไม่ได้นึกถึงชื่อที่เหมาะสม

แต่นอกเหนือจากนี้ฉันต้องสามารถซ่อนกิจกรรมที่เฉพาะเจาะจงสำหรับผู้สังเกตการณ์ที่เฉพาะเจาะจงแม้ว่าพวกเขาจะแนบกับพวกเขาผ่านกลุ่ม


นอกหัวข้อเล็กน้อย :

โดยส่วนตัวแล้วฉันรู้สึกว่าฉันควรจะสามารถตัดปัญหานี้ให้กลายเป็นปัญหาเล็ก ๆ น้อย ๆ ได้ แต่มันจะช่วยฉันได้อย่างไร ฉันคิดว่าเป็นเพราะมันมีฟังก์ชั่นเรียกซ้ำหลายอย่างที่ไม่เกี่ยวข้องกันและประเภทลูกค้าที่แตกต่างกันซึ่งจำเป็นต้องได้รับข้อมูลในรูปแบบที่แตกต่างกัน ฉันห่อหัวของฉันไม่ได้จริงๆ หากใครก็ตามสามารถแนะนำฉันในทิศทางของวิธีการที่ดีขึ้นในการแก้ปัญหาลำดับชั้นฉันยินดีที่จะรับสิ่งนั้นเช่นกัน


ฟังดูเหมือนปัญหาทฤษฎีกราฟ ดังนั้นเราจึงมีกราฟบางส่วนที่แสดงถึงลำดับชั้นของกลุ่ม แต่ละกลุ่มเป็นจุดยอดในกราฟ คุณสมบัติใดที่ถือเป็นจริง มันเป็นความจริงหรือไม่ที่มีจุดสุดยอดที่ไม่ซ้ำใครที่nมีองศาเป็น 0 เสมอในขณะที่จุดสุดยอดอื่น ๆ ทุกอันมีระดับอย่างน้อย 1 อยู่? จุดสุดยอดทุกจุดเชื่อมต่อกับnอะไร? เส้นทางสู่ความnเป็นเอกลักษณ์หรือไม่? หากคุณสามารถแสดงรายการคุณสมบัติของโครงสร้างข้อมูลและสรุปการทำงานของมันไปยังส่วนต่อประสาน - รายการของวิธีการ - เรา (I) อาจจะเกิดขึ้นกับการใช้งานโครงสร้างข้อมูลดังกล่าว

ขอขอบคุณสำหรับการตอบสนองของคุณ. มีหลายลำดับชั้นของกลุ่มที่ไม่ได้เชื่อมต่อกันยกเว้นผ่าน Observers แต่ฉันไม่คิดว่าพวกเขาเป็นส่วนหนึ่งของวัตถุกราฟพวกเขามีลิงก์ไปยังจุดยอดในพวกเขา แต่ละกลุ่มในลำดับชั้นสามารถมี 1 พาเรนต์เท่านั้น แต่ 0 .. * children คุณจะนำสิ่งนั้นไปใช้ในกราฟได้อย่างไร? และมีเพียงลำดับชั้นที่มี 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

ด้วยมุมมองที่ จำกัด เรามีข้อกำหนดการใช้งานหรือการใช้งานระบบของคุณยากที่จะระบุเฉพาะเจาะจงเกินไป ตัวอย่างเช่นสิ่งที่จะต้องพิจารณาอาจเป็น:

  • ระบบพร้อมกันสูง (มีผู้ใช้จำนวนมาก) หรือไม่
  • อัตราส่วนการอ่าน / เขียนของการเข้าถึงข้อมูลคืออะไร? (การอ่านสูงการเขียนต่ำเป็นเรื่องธรรมดา)

สำหรับรูปแบบอื่น ๆ ฉันจะกังวลน้อยลงเกี่ยวกับรูปแบบที่ถูกต้องในโซลูชันของคุณและเพิ่มเติมเกี่ยวกับการออกแบบโซลูชันจริง ฉันคิดว่าความรู้เกี่ยวกับรูปแบบการออกแบบนั้นมีประโยชน์ แต่ไม่ใช่ทั้งหมดและท้ายที่สุดทั้งหมด: เพื่อใช้การเปรียบเทียบนักเขียนรูปแบบการออกแบบนั้นเหมือนพจนานุกรมของวลีที่พบเห็นทั่วไปมากกว่าพจนานุกรมของประโยคที่คุณต้องเขียนทั้งเล่ม จาก.

ไดอะแกรมของคุณโดยปกติแล้วฉันจะโอเค

มีกลไกหนึ่งที่คุณไม่ได้กล่าวถึงและมีการจัดเรียงของแคชบางอย่างในลำดับชั้นของคุณ เห็นได้ชัดว่าคุณต้องใช้สิ่งนี้ด้วยความระมัดระวัง แต่มันสามารถปรับปรุงประสิทธิภาพของระบบของคุณได้อย่างมาก นี่เป็นเรื่องง่ายที่จะทำ (ข้อแม้ emator):

สำหรับแต่ละโหนดในลำดับชั้นของคุณให้จัดเก็บข้อมูลที่สืบทอดมาพร้อมกับโหนด ทำสิ่งนี้อย่างเกียจคร้านหรือเชิงรุกนั่นขึ้นอยู่กับคุณ เมื่อมีการอัพเดตลำดับชั้นคุณสามารถสร้างข้อมูลแคชสำหรับโหนดที่ได้รับผลกระทบทั้งหมดใหม่จากนั้นหรือตั้งค่าสถานะ 'สกปรก' ในสถานที่ที่เหมาะสมและสร้างข้อมูลที่ได้รับผลกระทบอีกครั้งเมื่อจำเป็น

ฉันไม่รู้ว่าสิ่งนี้เหมาะสมในระบบของคุณ แต่อาจคุ้มค่าที่จะพิจารณา

นอกจากนี้คำถามเกี่ยวกับ 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.