“ ลำดับชั้นการจัดวางองค์ประกอบลึก” นั้นไม่ดีเช่นกันใช่ไหม


19

ขออภัยถ้า "ลำดับชั้นการแต่งเพลง" ไม่ใช่เรื่องอะไร แต่ฉันจะอธิบายสิ่งที่ฉันหมายถึงในคำถาม

ไม่มีโปรแกรมเมอร์ OO ที่ยังไม่ได้พบกับรูปแบบของ "Keep hierarchies flat" หรือ "ชอบเรียงความมากกว่าการสืบทอด" และอื่น ๆ อย่างไรก็ตามลำดับชั้นขององค์ประกอบที่ลึกซึ้งดูเหมือนว่าจะมีปัญหาเช่นกัน

สมมติว่าเราต้องการชุดของรายงานที่มีรายละเอียดผลลัพธ์ของการทดสอบ:

class Model {
    // ... interface

    Array<Result> m_results;
}

ผลลัพธ์แต่ละรายการมีคุณสมบัติบางอย่าง สิ่งเหล่านี้รวมถึงเวลาของการทดสอบรวมถึงข้อมูลเมตาจากแต่ละขั้นตอนของการทดสอบ:

enum Stage {
    Pre = 1,
    Post
};

class Result {
    // ... interface

    Epoch m_epoch;
    Map<Stage, ExperimentModules> m_modules; 
}

โอเคเยี่ยมเลย ตอนนี้แต่ละโมดูลการทดสอบมีสตริงที่อธิบายผลลัพธ์ของการทดสอบรวมถึงชุดของการอ้างอิงไปยังชุดตัวอย่างการทดลอง:

class ExperimentalModules {
    // ... interface

    String m_reportText;
    Array<Sample> m_entities;
}

แล้วแต่ละตัวอย่างก็มี ... อืมคุณจะได้ภาพ

ปัญหาคือว่าถ้าฉันสร้างแบบจำลองวัตถุจากโดเมนแอปพลิเคชันของฉันดูเหมือนว่าจะเป็นแบบธรรมชาติมาก แต่ในตอนท้ายของวัน a Resultเป็นเพียงข้อมูลที่โง่เง่า! ดูเหมือนจะไม่คุ้มค่าที่จะสร้างชั้นเรียนขนาดใหญ่สำหรับมัน

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


ไม่เข้าใจส่วนบริบทภายนอก
Tulains Córdova

@ TulainsCórdovaสิ่งที่ฉันพยายามถามนี่คือ "มีสถานการณ์ที่องค์ประกอบลึกเป็นทางออกที่ดี"?
AwesomeSauce

ฉันเพิ่มคำตอบ
Tulains Córdova

5
ใช่แล้ว ปัญหาที่ผู้คนพยายามแก้ไขด้วยการแทนที่การสืบทอดด้วยการเรียบเรียงไม่ได้หายไปอย่างน่าอัศจรรย์เพียงเพราะคุณเปลี่ยนกลยุทธ์การรวมฟีเจอร์หนึ่งออกไปอีกอัน ทั้งคู่เป็นโซลูชั่นสำหรับการจัดการความซับซ้อนและความซับซ้อนนั้นยังคงอยู่ที่นั่นและจะต้องได้รับการจัดการในบางวิธี
Mason Wheeler

3
ฉันไม่เห็นอะไรผิดปกติกับตัวแบบข้อมูลที่ลึก แต่ฉันก็ไม่เห็นว่าคุณจะสร้างแบบจำลองนี้ด้วยการสืบทอดได้อย่างไรเนื่องจากเป็นความสัมพันธ์แบบ 1: N ในแต่ละเลเยอร์
usr

คำตอบ:


17

นี่คือสิ่งที่กฎหมายของ Demeter / หลักการของความรู้อย่างน้อยเกี่ยวกับ ผู้ใช้Modelไม่จำเป็นต้องรู้เกี่ยวกับExperimentalModulesอินเทอร์เฟซ 'เพื่อทำงานของพวกเขา

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

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

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

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

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


คุณพูดถึงความกังวลหลักที่ฉันมี; ความคิดที่ว่าฉันต้องไปให้ไกลเพื่อนำไปใช้ในการทำสิ่งที่มีประโยชน์ในระดับที่สูงขึ้นของสิ่งที่เป็นนามธรรม การอภิปรายที่มีประโยชน์มากขอบคุณ
AwesomeSauce

7

“ ลำดับชั้นการจัดวางองค์ประกอบลึก” นั้นไม่ดีเช่นกันใช่ไหม

แน่นอน. กฎควรพูดว่า "รักษาลำดับชั้นทั้งหมดให้เรียบที่สุดเท่าที่จะทำได้"

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

ตัวอย่างของคุณไม่ทำให้ฉันเป็น "ลำดับชั้นลึก" แบบฟอร์มสืบทอดมาจากสี่เหลี่ยมซึ่งสืบทอดมาจากชุดของจุดที่สืบทอดมาจากพิกัด x และ y และฉันยังไม่ได้รับไอน้ำเต็มหัวเลย


4

การถอดความไอน์สไตน์:

รักษาลำดับชั้นทั้งหมดให้เรียบที่สุดเท่าที่จะทำได้แต่ไม่ราบเรียบ

หมายความว่าหากปัญหาที่คุณกำลังสร้างโมเดลเป็นเช่นนั้นคุณไม่ควรมีความรู้เกี่ยวกับการสร้างแบบจำลองเหมือนเดิม

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


1

ใช่คุณสามารถสร้างแบบจำลองเหมือนตารางสัมพันธ์

Result {
    Id
    ModelId
    Epoch
}

เป็นต้นซึ่งมักจะนำไปสู่การเขียนโปรแกรมที่ง่ายขึ้นและการทำแผนที่ง่าย ๆ ไปยังฐานข้อมูล แต่ค่าใช้จ่ายของการสูญเสียการเข้ารหัสที่ยากลำบากของความสัมพันธ์ของคุณ


0

ฉันไม่รู้วิธีแก้ปัญหานี้ใน Java เพราะ Java สร้างขึ้นจากแนวคิดที่ว่าทุกสิ่งเป็นวัตถุ คุณไม่สามารถระงับคลาสกลางด้วยการแทนที่ด้วยพจนานุกรมเนื่องจากชนิดใน blobs ข้อมูลของคุณมีความหลากหลาย (เช่น timestamp + list หรือ string + list ... ) ทางเลือกของการแทนที่คลาสของคอนเทนเนอร์ด้วยฟิลด์ (เช่นส่งผ่านตัวแปร "m_epoch" ด้วย "m_modules") นั้นแย่มากเพราะมันกำลังสร้างออบเจ็กต์แบบปริยาย ประโยชน์.

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.