เกือบทุกโครงการที่มีแบบจำลองหรือเอกสารที่แก้ไขได้จะมีโครงสร้างแบบลำดับชั้น มันมีประโยชน์ในการใช้ 'โหนดลำดับชั้น' เป็นคลาสพื้นฐานสำหรับเอนทิตีที่แตกต่างกัน บ่อยครั้งที่รายการเชื่อมโยง (พี่น้องตระกูลรุ่นที่ 2) เป็นวิธีธรรมชาติที่ห้องสมุดชั้นเรียนเติบโตขึ้นอย่างไรก็ตามเด็ก ๆ อาจมีหลากหลายประเภทและอาจเป็น " โมเดลวัตถุ " ไม่ใช่สิ่งที่เราพิจารณาเมื่อพูดถึงต้นไม้โดยทั่วไป
การใช้ tree (node) ที่เป็นที่โปรดปรานในโมเดลแรกของคุณคือ one-liner (ใน C #):
public class node : List<node> { /* props go here */ }
รับช่วงจากรายการทั่วไปของประเภทของคุณ (หรือสืบทอดจากการรวบรวมทั่วไปอื่น ๆ ที่เป็นประเภทของคุณเอง) การเดินเป็นไปได้ในทิศทางเดียว: สร้างรูตลง (รายการไม่รู้จักพ่อแม่)
ต้นไม้ของผู้ปกครองเท่านั้น
แบบจำลองอื่นที่คุณไม่ได้กล่าวถึงคือรุ่นที่เด็กทุกคนมีการอ้างอิงถึงผู้ปกครอง:
null
|
+---------+---------------------------------+
| parent |
| root |
+-------------------------------------------+
| | |
+---------+------+ +-------+--------+ +--+-------------+
| parent | | parent | | parent |
| node 1 | | node 2 | | node 3 |
+----------------+ +----------------+ +----------------+
การเดินทรีนี้เป็นไปได้เฉพาะในทางกลับกันโดยปกติแล้วโหนดเหล่านี้ทั้งหมดจะถูกเก็บไว้ในคอลเลกชัน (อาเรย์, แฮชเทเบิล, พจนานุกรม ฯลฯ ) และโหนดจะอยู่ที่การค้นหาคอลเล็กชันตามเกณฑ์อื่น ต้นไม้ซึ่งโดยทั่วไปแล้วจะไม่ได้มีความสำคัญหลัก
โดยทั่วไปแล้วจะเห็นต้นไม้ของต้นไม้เท่านั้นในแอปพลิเคชันฐานข้อมูล การค้นหาโหนดย่อยของโหนดทำได้ง่ายด้วยคำสั่ง "SELECT * WHERE ParentId = x" อย่างไรก็ตามเราไม่ค่อยพบสิ่งเหล่านี้เปลี่ยนเป็นวัตถุคลาสต้นไม้โหนด ในแอปพลิเคชั่น statefull (เดสก์ท็อป) อาจถูกห่อไว้ในการควบคุมทรีโหนดที่มีอยู่ ในแอปพลิเคชันไร้สาย (เว็บ) แม้อาจเป็นไปได้ยาก ฉันได้เห็นเครื่องมือสร้างคลาส ORM การจับคู่โยนข้อผิดพลาดล้นสแตกเมื่อสร้างคลาสสำหรับตารางที่มีความสัมพันธ์กับตัวเอง (หัวเราะหึ ๆ ) ดังนั้นต้นไม้เหล่านี้อาจไม่เหมือนกัน
ต้นไม้นำทางแบบสองทิศทาง
อย่างไรก็ตามในกรณีที่ใช้งานได้จริงมันสะดวกที่จะมีสิ่งที่ดีที่สุดทั้งสองโลก โหนดที่มีรายการลูก ๆ และรู้จักพ่อแม่ของพวกมันด้วย: ต้นไม้นำทางสองทิศทาง
null
|
+--------------------+--------------------+
| parent |
| root |
| child1 child2 child3 |
+--+------------------+----------------+--+
| | |
+---------+-----+ +-------+-------+ +---+-----------+
| parent | | parent | | parent |
| node1 | | node2 | | node3 |
| child1 child2 | | child1 child2 | | child1 child2 |
+--+---------+--+ +--+---------+--+ +--+---------+--+
| | | | | |
สิ่งนี้นำมาซึ่งแง่มุมอื่น ๆ อีกมากมายที่ควรพิจารณา:
- จะใช้การเชื่อมโยงและยกเลิกการเชื่อมโยงของผู้ปกครองได้ที่ไหน
- ปล่อยให้บิสซิเนสลอจิกดูแลและปล่อยให้มุมมองออกไปจากโหนด (พวกมันจะลืม!)
- โหนดมีวิธีในการสร้างลูก (ไม่อนุญาตให้เรียงลำดับใหม่) (ตัวเลือกของ Microsoft ในการใช้งาน System.Xml.XmlDocument DOM ซึ่งเกือบทำให้ฉันบ้าเมื่อฉันเจอครั้งแรก)
- โหนดนำพาเรนต์ไปยังคอนสตรัคเตอร์ของพวกเขา (ไม่อนุญาตให้เรียงลำดับใหม่)
- ในวิธีการเพิ่มทั้งหมด (), แทรก () และลบ () และโอเวอร์โหลดของโหนด (โดยปกติจะเป็นตัวเลือกของฉัน)
- ติดตา
- วิธีการเดินต้นไม้เมื่อยังคงอยู่ (เช่นออกจากลิงค์ผู้ปกครอง)
- วิธีสร้างการเชื่อมโยงแบบสองทางใหม่หลังจากยกเลิกการทำให้เป็นอนุกรม (ตั้งค่าผู้ปกครองทั้งหมดอีกครั้งเป็นการดำเนินการภายหลังการดีซีเรียลไลซ์เซชัน)
- การแจ้งเตือน
- กลไกแบบคงที่ (ธง IsDirty) จัดการในคุณสมบัติแบบเรียกซ้ำ?
- เหตุการณ์ฟองสบู่ผ่านผู้ปกครอง, ลงผ่านเด็ก ๆ , หรือทั้งสองวิธี (พิจารณาตัวอย่างเช่นปั๊มข้อความ windows)
ตอนนี้เพื่อตอบคำถามต้นไม้นำทางสองทิศทางมีแนวโน้มที่จะ (ในอาชีพและทุ่งนาของฉัน) ที่ใช้กันอย่างแพร่หลาย ตัวอย่างคือการใช้งาน Microsoft ของ System.Windows.Forms.Control หรือ System.Web.UI.Control ในกรอบงาน. Net แต่การใช้งาน DOM (Document Object Model) ทุกรุ่นจะมีโหนดที่รู้จักพาเรนต์รวมถึงการแจงนับ ของเด็ก ๆ เหตุผล: ความง่ายในการใช้งานมากกว่าความง่ายในการใช้งาน นอกจากนี้เหล่านี้มักจะเป็นคลาสพื้นฐานสำหรับคลาสที่เฉพาะเจาะจงมากขึ้น (XmlNode อาจเป็นฐานของคลาสแท็กแอตทริบิวต์และข้อความ) และคลาสพื้นฐานเหล่านี้เป็นสถานที่ตามธรรมชาติเพื่อวางลำดับทั่วไปและสถาปัตยกรรมการจัดการเหตุการณ์
ต้นไม้วางตัวอยู่ในใจกลางของสถาปัตยกรรมจำนวนมากและความสามารถในการนำทางได้อย่างอิสระหมายถึงความสามารถในการนำโซลูชั่นไปใช้อย่างรวดเร็ว