คลาสที่ซ้อนกันต่ำกว่าระดับหรือไม่


9

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

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

นี่คือตัวอย่างสองตัวอย่างที่ฉันเพิ่งใช้เพื่อ: https://gist.github.com/3975581 - สิ่งแรกที่ช่วยให้ฉันเก็บรักษาสิ่งที่สืบทอดมาได้อย่างแน่นหนาด้วยกันครั้งที่สองให้ฉันเข้าถึงสมาชิกที่ได้รับความคุ้มครองจากพนักงาน ...


ฉันแค่อยากจะบอกว่าขอบคุณสำหรับคำตอบ / ข้อมูลเชิงลึก - ฉันไม่แน่ใจว่าจะเลือกคำตอบอย่างไรดังนั้นฉันจะทิ้งมันไว้ในขณะที่ฉันครุ่นคิดถึงคำแนะนำที่ฉันได้รับและทบทวน ...
Aaron Anodide

คำตอบ:


6

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

แม้ว่าการมีอยู่ของคลาสที่มีการมองเห็นการชุมนุมและการแนะนำของ lambdas ได้ลดความจำเป็นในการเรียนซ้อน*ลงอย่างมีนัยสำคัญพวกเขายังคงเป็นตัวเลือกการออกแบบที่ถูกต้อง แม้ว่าจะมีการซ้อนทับบางอย่างกับคลาสภายในภายในเนมสเปซคุณลักษณะคลาสที่ซ้อนกันนั้นไม่ซ้ำกันในการให้คุณซ่อนคลาสภายในคลาสอื่นทั้งหมด


*การใช้คุณสมบัติที่คล้ายกันใน Java นั้นสูงกว่ามากเนื่องจากมีตัวเลือกอื่น ๆ ใน C # ที่ไม่ได้อยู่ใน Java


มันดีหรือไม่ที่จะซ่อนคลาสทั้งหมดในคลาสอื่นตามสาระสำคัญของการออกแบบ OOP
Maxood

1
@ Maxood มันเป็นการดีที่จะซ่อนชั้นเรียนถ้าคุณสามารถซ่อนมันได้ ผู้ใช้ API ของคุณควรรู้น้อยที่สุดเกี่ยวกับวิธีการนำ API ของคุณไปใช้
dasblinkenlight

3

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

ดังนั้นสิ่งที่ควรทำให้ OOP ยิ่งใหญ่ (reusability) หายไปจากที่นี่ นอกจากนี้สิ่งที่คุณสามารถประสบความสำเร็จในชั้นเรียนซ้อนกันที่คุณไม่สามารถบรรลุด้วยวิธีการธรรมดาและสมาชิกส่วนตัวภายในชั้นผู้ปกครอง

สำหรับรูปแบบการใช้ซอฟต์แวร์ที่มีประโยชน์การเรียนซ้อนกันดูที่นี่


10
ฉันไม่เคยซื้อสิ่งที่นำกลับมาใช้ใหม่ได้อย่างน้อยก็ไม่ใช่วิธีที่จะนำมาใช้ (1) การเรียกใช้รหัส / คลาสที่มีอยู่ (ซึ่งคุณดูเหมือนจะพูดถึงและที่ฉันมักจะเห็นว่าเป็นคำจำกัดความของการใช้ซ้ำ) ไม่มีอะไรเกี่ยวข้องกับ OOP มันเป็นแค่โมดูลพื้นฐานพื้นฐาน (2) Subtype polymorphism ซึ่งเป็นลักษณะการกำหนดหนึ่งเดียวของ OOP ทำให้สามารถนำรหัสลูกค้ากลับมาใช้ใหม่ได้โดยการใช้งานเฉพาะที่ไม่เกี่ยวข้องกล่าวคือมันทำงานในลักษณะเดียวกันหรือไม่ว่าชั้นคอนกรีตสามารถเข้าถึงได้หรือไม่ IOW ฉันนำมาใช้ซ้ำได้ แต่มันก็ใช้ได้กับคลาสที่ซ้อนกันเช่นกัน

1
ฉันจะบอกว่ายังมีฉนวนกันความร้อน namespace ที่กำหนดโดยระดับผู้ปกครอง - ดังนั้นหากคุณต้องการทั้งชั้นเรียน A และ B อาจมี "Params" ซ้อนกันในชั้นเรียนและการเข้าถึงสมาชิกที่ไม่ใช่แบบสาธารณะของชั้นที่มี พวกเขาทั้งสองเหตุผลที่จะมีชั้นเรียนภายในที่ใช้นอกชั้นเรียนหรือไม่
Aaron Anodide

@AaronAnodide นั่นควรเป็นคำตอบเกี่ยวกับวิธีการใช้คลาสที่ซ้อนกัน มันเป็นวิธี / เหตุผลที่ฉันใช้พวกมันช่วยในการจัดระเบียบรหัส
Izkata

2

am I going down an inherintly bad path

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

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

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

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

arm newArm = new Body.torso.side.arm("");

1

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


1

ในประสบการณ์ของฉันเรียนซ้อน

  • กลับมาหลอกหลอนฉัน
  • ถูกนำมาใช้เมื่อฉันต้องการที่จะตัดมุม
  • ทำการทดสอบฝันร้าย
  • มีผลกระทบด้านลบต่อการแยกข้อกังวลและการออกแบบโดยรวม

ลองดูชั้นเรียนของคุณแล้วฉันก็คิดว่า:

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

ทำไมไม่แยกคลาสของคุณออกเป็นหลายคลาส เช่น

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