คุณทำตามกฎ“ No Dependency Cycle” อย่างเคร่งครัดเพียงใด (ขึ้นอยู่กับ)


10

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

เพื่อความชัดเจน: ภายใต้ "วงจรการพึ่งพา" ฉันเข้าใจการอ้างอิงแบบวงกลมระหว่างสองเนมสเปซ

ขณะนี้ฉันกำลังทำงานบนกรอบ GUI ที่ใช้ Windows CE สำหรับเครื่องมือฝังตัว - แค่คิดถึงแพลตฟอร์มกราฟิก Android แต่สำหรับเครื่องมือต่ำสุด เฟรมเวิร์กเป็นชุดประกอบเดี่ยวที่มีรหัสประมาณ 50,000 บรรทัด (ไม่รวมการทดสอบ) เฟรมเวิร์กแบ่งออกเป็นเนมสเปซต่อไปนี้:

  • ระบบนำทางหลัก & ระบบย่อยเมนู
  • ระบบย่อยของหน้าจอ (ผู้นำเสนอ / การดู / ... )
  • ชั้นควบคุม / Widget

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

ดังนั้นคำถามของฉัน: คุณปฏิบัติตามกฎ "รอบการพึ่งพาไม่มี" อย่างเคร่งครัดอย่างไร การปรับระดับเป็นสิ่งสำคัญจริง ๆ หรือไม่


2
ถ้า "ไม่มีวงจรการพึ่งพา" หมายถึงไม่มีการอ้างอิงแบบวงกลมดังนั้น - ไม่มีข้อแก้ตัว นั่นคือความชั่วร้ายที่บริสุทธิ์
Arnis Lapsa

@ollifant: กำหนดสิ่งที่คุณหมายถึงว่าเมื่อคุณเขียน "No Dependency Cycle" ระหว่างชั้นหรือระหว่างชั้นภายในชั้น?
Doc Brown

คำตอบ:


9

ฉันเพิ่งเขียนหนังสือสีขาว 2 เล่มเผยแพร่บน Simple-Talk เกี่ยวกับหัวข้อของรหัสสถาปัตยกรรม. NET (หนังสือเล่มที่ 1 เป็นเรื่องเกี่ยวกับ. NET แอสเซมบลี. เล่มที่สองเกี่ยวกับ namespaces และการปรับระดับ):

การแบ่งพาร์ติชันรหัสของคุณผ่านแอสเซมบลี. NET และโครงการ Visual Studio

การกำหนด. NET Components ด้วย Namespaces

การปรับระดับเป็นสิ่งสำคัญจริง ๆ หรือไม่

ใช่แล้ว!

อ้างอิงจากหนังสือสีขาวเล่มที่ 2:

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

( ... )

ตราบใดที่ข้อ จำกัด ของส่วนประกอบ acyclic ได้รับการเคารพอย่างต่อเนื่องฐานรหัสยังคงสามารถเรียนรู้และบำรุงรักษาได้สูง

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

6

ฉันไม่อนุญาตให้มีการอ้างอิงแบบวนรอบระหว่างคลาสหรือเนมสเปซ ใน C #, Java และ C ++ คุณสามารถหยุดการพึ่งพาคลาสแบบวงกลมได้เสมอโดยการแนะนำอินเตอร์เฟส

การทดสอบการเข้ารหัสครั้งแรกทำให้เป็นการยากที่จะแนะนำการพึ่งพาแบบวงกลม


4

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

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

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

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


2

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

สิ่งนี้กล่าวว่า John Lakos เข้มงวดมากเกี่ยวกับการกำจัดรอบ (build-time) ทั้งหมด บ็อบมาร์ตินยอมรับทัศนคติว่ามีเพียงวัฏจักรระหว่างไบนารี (เช่น DLLs, ปฏิบัติการ) มีความสำคัญและควรหลีกเลี่ยง เขาเชื่อว่าวัฏจักรระหว่างคลาสภายในไบนารีไม่สำคัญอย่างยิ่ง

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

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


0

เกือบทั้งหมดเนื่องจากวงจรการพึ่งพาชนิดบิลด์ไม่สะดวกใน Haskell และเป็นไปไม่ได้ใน Agda และ Coq และเป็นภาษาที่ฉันใช้

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