มีรสชาติของ OOP ที่หลักการ SOLID บางส่วนหรือทั้งหมดขัดแย้งกับการทำความสะอาดรหัสหรือไม่?


26

ฉันเพิ่งได้พูดคุยกับเพื่อนของฉันเกี่ยวกับ OOP ในการพัฒนาวิดีโอเกม

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

ความกังวลของเขาคือจำนวนชั้นเรียนจำนวนมากจะแปลฝันร้ายบำรุงรักษา มุมมองของฉันคือว่ามันจะมีผลตรงกันข้ามที่แน่นอน เราดำเนินการหารือเกี่ยวกับเรื่องนี้สำหรับสิ่งที่ดูเหมือนว่าหลายศตวรรษในที่สุดก็ตกลงที่จะไม่เห็นด้วยบอกว่าอาจมีบางกรณีที่หลักการที่เป็นของแข็งและ OOP ที่เหมาะสมไม่จริงผสมกันได้ดี

แม้แต่รายการ Wikipediaเกี่ยวกับหลักการ SOLID ก็ระบุว่าเป็นแนวทางที่ช่วยในการเขียนโค้ดที่สามารถบำรุงรักษาได้และเป็นส่วนหนึ่งของกลยุทธ์โดยรวมของการเขียนโปรแกรมแบบคล่องตัวและปรับตัว

ดังนั้นคำถามของฉันคือ:

มีกรณีใน OOP ที่หลักการ SOLID บางส่วนหรือทั้งหมดไม่ได้ยืมตัวเองเพื่อทำความสะอาดรหัสหรือไม่?

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

มีคนอื่นไหม? บางทีโครงการบางประเภทหรือแพลตฟอร์มเป้าหมายบางอย่างอาจทำงานได้ดีขึ้นด้วยวิธี SOLID ที่น้อยลง?

แก้ไข:

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

หากคุณอยากรู้เกี่ยวกับโครงการของฉันให้ดูนี้

แก้ไข 2:

ฉันจินตนาการว่าคำถามนี้จะตอบในหนึ่งใน 3 วิธี:

  1. ใช่มีหลักการออกแบบของ OOP ที่ขัดแย้งกับ SOLID บางส่วน
  2. ใช่มีหลักการออกแบบของ OOP ที่ขัดแย้งกับ SOLID อย่างสมบูรณ์
  3. ไม่ SOLID เป็นหัวเข่าของผึ้งและ OOP จะดีขึ้นตลอดไป แต่เช่นเดียวกับทุกสิ่งมันไม่ใช่ยาครอบจักรวาล ดื่มอย่างรับผิดชอบ

ตัวเลือกที่ 1 และ 2 น่าจะสร้างคำตอบที่ยาวและน่าสนใจ ในทางกลับกันตัวเลือกที่ 3 น่าจะเป็นคำตอบที่สั้นไม่น่าสนใจ

ดูเหมือนว่าเราจะเข้าหาทางเลือกที่ 3


คุณนิยาม 'รหัสสะอาด' เป็นอย่างไร?
GrandmasterB

โค้ดที่สะอาดในขอบเขตของคำถามนี้คือโครงสร้างโค้ดในวิธีที่ตรงตามเป้าหมายของ OOP และชุดของหลักการออกแบบที่เลือก ดังนั้นฉันคุ้นเคยกับโค้ดที่สะอาดในแง่ของเป้าหมายที่กำหนดโดย OOP + SOLID ฉันสงสัยว่ามีอีกชุดของหลักการออกแบบที่ทำงานกับ OOP แต่เข้ากันไม่ได้ทั้งหมดหรือบางส่วนกับ SOLID
MetaFight

1
ฉันกังวลเกี่ยวกับการเล่นเกมของคุณมากกว่าเรื่องอื่น นอกจากว่าเรากำลังพูดถึงเกมข้อความ
ร่าเริง

1
เกมนี้เป็นการทดลอง ฉันลองใช้วิธีการพัฒนาที่แตกต่างกันและฉันก็พยายามดูว่ารหัส Enterprise-y สามารถทำงานได้เมื่อเขียนเกมหรือไม่ ฉันคาดหวังว่าการแสดงจะเป็นปัญหา แต่ก็ยังไม่เป็นเช่นนั้น ถ้า / เมื่อไหร่สิ่งต่อไปที่ฉันจะทดลองคือวิธีปรับรหัสของฉันให้เป็นรหัสนักแสดง การเรียนรู้มากมาย!
MetaFight

1
ที่เสี่ยงต่อการ downvotes บางอย่างที่ผมอยากจะกลับไป "ทำไม" คำถาม: OOP ในการพัฒนาเกม เนื่องจากลักษณะของการพัฒนาเกม OOP "ดั้งเดิม" ดูเหมือนว่าจะหลุดพ้นจากความนิยมในรสชาติของระบบเอนทิตี้ / ส่วนประกอบต่าง ๆ ตัวแปรที่น่าสนใจที่นี่เช่น นี่ทำให้ฉันคิดว่าคำถามไม่ควรเป็น "SOLID + OOP" แต่ "OOP + การพัฒนาเกม" เมื่อคุณดูกราฟปฏิสัมพันธ์ของวัตถุสำหรับเกม dev เทียบกับแอปพลิเคชันระดับ N ความแตกต่างอาจหมายถึงกระบวนทัศน์ใหม่นั้นดี
J Trana

คำตอบ:


20

มีกรณีใน OOP ที่หลักการ SOLID บางส่วนหรือทั้งหมดไม่ได้ยืมตัวเองเพื่อทำความสะอาดรหัสหรือไม่?

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

ตอนนี้อาจมีบางกรณีที่หลักการของ SOLID ชนกับ DRY (อย่าทำซ้ำตัวเอง), KISS (ทำให้โง่อย่างง่าย ๆ ) หรือหลักการอื่น ๆ ของการออกแบบ OO ที่ดี และแน่นอนพวกเขาสามารถปะทะกับความเป็นจริงของข้อกำหนดข้อ จำกัด ของมนุษย์ข้อ จำกัด ของภาษาโปรแกรมของเราอุปสรรคอื่น ๆ

กล่าวโดยย่อหลักการของ SOLID จะให้ยืมตัวเองเพื่อทำความสะอาดรหัส แต่ในบางสถานการณ์พวกเขาจะให้ยืมตัวเองน้อยกว่าทางเลือกที่ขัดแย้งกัน พวกเขาดีเสมอ แต่บางครั้งสิ่งอื่น ๆก็ดีกว่า


14
ฉันชอบแต่บางครั้งสิ่งอื่น ๆ ก็ดีกว่า มันมี "Animal Farm" ให้ความรู้สึก ;)
FrustratedWithFormsDesigner

12
+1 เมื่อฉันดูหลักการของ SOLID ฉันเห็น 5 "เป็นคนที่น่ารัก" แต่ไม่มีพวกเขาอันดับสูงสุด DRY, KISS และ "ทำให้ความตั้งใจของคุณชัดเจน" ใช้ SOLID แต่แสดงความระมัดระวังและความสงสัย
949300

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

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

... และนำไปใช้อย่างมีประสิทธิภาพเมื่อใช้กับคลาสพื้นฐานที่สามารถทำได้ หากมีการรวมรายการสิบล้านรายการซึ่งรู้จำนวนของมันและรายการห้ารายการที่สามารถดึงรายการตามลำดับได้เท่านั้นการร้องขอรายการ 10,000,003rd ควรอ่านการนับจากรายการแรกจากนั้นอ่านสามรายการจากวินาที . อินเทอร์เฟซสำหรับอ่างครัวอาจละเมิด ISP แต่สามารถปรับปรุงประสิทธิภาพการทำงานได้อย่างมากในบางองค์ประกอบ / การรวมสถานการณ์
supercat

13

ฉันคิดว่าฉันมีมุมมองที่ผิดปกติในการทำงานด้านการเงินและเกม

โปรแกรมเมอร์หลายคนที่ฉันพบในเกมนั้นแย่มากที่ Software Engineering - แต่พวกเขาก็ไม่จำเป็นต้องฝึกหัดอย่าง SOLID ตามเนื้อผ้าพวกเขาวางเกมลงในกล่องแล้วเสร็จ

ในด้านการเงินฉันพบว่านักพัฒนาสามารถเลอะเทอะและไร้ระเบียบเพราะพวกเขาไม่ต้องการประสิทธิภาพที่คุณทำในเกม

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

ไม่ได้หมายความว่า SOLID จะไม่วิจารณ์ พวกเขาถูกเรียกว่าหลักการและพวกเขาควรจะปฏิบัติตามแนวทาง ดังนั้นเมื่อฉันควรทำตามพวกเขา? ฉันควรทำผิดกฎเมื่อใด

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

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

ฉันเห็นโค้ดที่มีหลายเลเยอร์ซึ่งไม่มีความรับผิดชอบ คลาสที่ไม่ได้ทำอะไรนอกจากสถานะการส่งผ่านจากคลาสหนึ่งไปอีกคลาสหนึ่ง ปัญหาคลาสสิกของการอ้อมมากเกินไป

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

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

ข้อโต้แย้งของคุณเกี่ยวกับ LSP ค่อนข้างเป็นไปตามสมมุติฐานและฉันไม่เข้าใจจริงๆว่าคุณหมายถึงอะไรโดยการรับมรดกที่ปลอดภัยรูปแบบอื่น?

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

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

โซลิดในตัวมันเองไม่เพียงพอสำหรับคุณที่จะเขียนโค้ดที่สะอาด ฉันเคยเห็นหนังสือของโรเบิร์ตซีมาร์ติน " รหัสสะอาด: คู่มือของงานฝีมือซอฟต์แวร์เปรียว " ปัญหาที่ใหญ่ที่สุดคือมันเป็นเรื่องง่ายที่จะอ่านหนังสือเล่มนี้และตีความมันเป็นกฎ หากคุณทำเช่นนั้นคุณจะพลาดจุด มันมีรายการของกลิ่น, ฮิวริสติกและหลักการมากมาย - มากกว่าห้าจาก SOLID หลักการทั้งหมดนี้ไม่ได้มีหลักการ แต่เป็นแนวทาง ลุง Bob เข้ามาพวกเขาในฐานะ "cubby hole" สำหรับแนวคิด มันเป็นการกระทำที่สมดุล การปฏิบัติตามคำแนะนำใด ๆ ที่สุ่มสี่สุ่มห้าจะทำให้เกิดปัญหา


1
หากคุณมีพารามิเตอร์คอนสตรัคจำนวนมากแนะนำว่าคุณละเมิด SRP แต่คอนเทนเนอร์ DI จะลบความเจ็บปวดที่เกี่ยวข้องกับพารามิเตอร์คอนสตรัคเตอร์จำนวนมากอยู่แล้วดังนั้นฉันจึงไม่เห็นด้วยกับข้อความสั่งของคุณเกี่ยวกับกรมทรัพย์สินทางปัญญา
Stephen

หลักการทั้งหมดนี้ไม่ได้มีหลักการ แต่เป็นแนวทาง มันเป็นการกระทำที่สมดุล อย่างที่ฉันบอกในโพสต์ของฉันที่ติดตาม SRP ด้วยตัวของมันเองที่รุนแรงอาจเป็นปัญหาได้
Dave Hillier

คำตอบที่ดี +1 สิ่งหนึ่งที่ฉันต้องการเพิ่ม: ฉันอ่านบทวิจารณ์ของ Skeet เพิ่มเติมเกี่ยวกับการวิจารณ์คำนิยามหนังสือเรียนมาตรฐานของ OCP ไม่ใช่แนวคิดหลักที่อยู่เบื้องหลัง OCP เพื่อความเข้าใจของฉันแนวคิดการผันแปรที่ได้รับการป้องกันคือสิ่งที่ OCP ควรได้รับตั้งแต่แรก
Doc Brown

5

นี่คือความคิดเห็นของฉัน:

แม้ว่าหลักการของ SOLID จะมุ่งไปที่ codebase ที่ไม่ซ้ำซ้อนและยืดหยุ่น แต่นี่อาจเป็นการแลกเปลี่ยนในการอ่านและการบำรุงรักษาหากมีคลาสและเลเยอร์มากเกินไป

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

ฉันเดาว่าหลักการของ SOLID นั้นไม่เห็นด้วยกับ OOP แต่ก็ยังคงเป็นไปได้ที่จะเขียนโค้ดที่ไม่สะอาดตามพวกเขา


3
+1 ตามคำนิยามเกือบระบบที่มีความยืดหยุ่นสูงจะต้องบำรุงรักษาได้น้อยกว่าระบบที่ยืดหยุ่นน้อยกว่า ความยืดหยุ่นมาในราคาเนื่องจากความซับซ้อนที่เพิ่มเข้ามา
Andy

@Andy ไม่จำเป็นต้อง ที่งานปัจจุบันของฉันชิ้นส่วนที่แย่ที่สุดของรหัสยุ่งเพราะมันถูกโยนเข้าด้วยกันโดย "ทำอะไรที่ง่าย ๆ แค่แฮ็คมันเข้าด้วยกันและทำให้มันทำงานได้ดังนั้นมันจึงไม่ซับซ้อน" เป็นผลให้หลายส่วนของระบบมีความแข็งแกร่ง 100% คุณไม่สามารถแก้ไขได้เลยโดยไม่ต้องเขียนใหม่ส่วนใหญ่ มันยากมากที่จะรักษา การบำรุงรักษามาจากการรวมตัวสูงและการมีเพศสัมพันธ์ต่ำไม่ใช่จากความยืดหยุ่นของระบบ
sara

3

ในวันแรก ๆ ของฉันฉันเริ่มเขียน Roguelike ใน C ++ เมื่อฉันต้องการใช้วิธีการเชิงวัตถุที่ดีฉันเรียนรู้จากการศึกษาของฉันฉันเห็นรายการเกมเป็นวัตถุ C ++ ทันที Potion, Swords, Food, Axe, Javelinsฯลฯ ทั้งหมดมาจากหลักพื้นฐานItemรหัส, การจัดการชื่อไอคอน, น้ำหนัก, ชนิดของสิ่งที่

จากนั้นฉันเขียนรหัสลอจิกของกระเป๋าและประสบปัญหา ฉันสามารถใส่Itemsในกระเป๋า แต่แล้วถ้าผมเลือกหนึ่งฉันจะรู้ว่าถ้ามันเป็นPotionหรือSword? ฉันค้นหาบนอินเทอร์เน็ตเพื่อดูวิธีลดรายการ ฉันแฮ็กคอมไพเลอร์ตัวเลือกเพื่อเปิดใช้งานข้อมูลรันไทม์ดังนั้นฉันจะรู้ว่าItemประเภทนามธรรมที่แท้จริงของฉันคืออะไรและเริ่มสลับตรรกะในประเภทเพื่อทราบว่าการดำเนินการที่ฉันอนุญาตคืออะไร (เช่นหลีกเลี่ยงการดื่มSwordsและวางPotionsเท้า)

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

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


2
ปัญหาคือประเภทที่สับสนกับคลาสของค่า (หมายเหตุ: ฉันไม่ได้ใช้คลาสคำเพื่ออ้างอิงแนวคิด OOP / C ++ ของคลาส) มีวิธีการแสดงจุดในระนาบคาร์ทีเซียนมากกว่าหนึ่งวิธี (พิกัดสี่เหลี่ยมขั้ว พิกัด) แต่มันเป็นส่วนหนึ่งของประเภทเดียวกันทั้งหมด อย่างไรก็ตามภาษา OOP หลักไม่สนับสนุนการจำแนกค่าตามธรรมชาติ สิ่งที่ใกล้เคียงที่สุดคือสหภาพของ C / C ++ แต่คุณต้องเพิ่มเขตข้อมูลพิเศษเพื่อที่จะรู้ว่าสิ่งที่คุณใส่ไว้ในนั้น
Doval

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

1
@Eurhoric ฉันพยายามอย่างหนัก ฉันมีวิธีการเชิงวัตถุ มีความแตกต่างระหว่างการมีวิธีการและประสบความสำเร็จการดำเนินการนั้นแม้ว่า :)
อาร์เธอร์ Havlicek

2
นี่เป็นตัวอย่างของหลักการ SOLID ที่ทำงานตรงกันข้ามกับการล้างโค้ดใน OOP อย่างไร ดูเหมือนว่าจะเป็นตัวอย่างของการออกแบบที่ไม่ถูกต้อง - นี่คือ orthogonal ถึง OOP!
Andres F.

1
คลาสไอเท็มพื้นฐานของคุณควรมีเมธอดบูลีน "canXXXX" เป็นจำนวนมากซึ่งการตั้งค่าเริ่มต้นเป็น FALSE ทั้งหมด จากนั้นคุณสามารถตั้งค่า "canThrow ()" เพื่อคืนค่าจริงในคลาส Javelin ของคุณและ canEat () เพื่อคืนค่าจริงสำหรับคลาส Postion ของคุณ
James Anderson

3

ความกังวลของเขาคือจำนวนชั้นเรียนจำนวนมากจะแปลฝันร้ายบำรุงรักษา มุมมองของฉันคือว่ามันจะมีผลตรงกันข้ามที่แน่นอน

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

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

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

ป้อนคำอธิบายรูปภาพที่นี่

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

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

ป้อนคำอธิบายรูปภาพที่นี่

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

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

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

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

ป้อนคำอธิบายรูปภาพที่นี่

มีกรณีใน OOP ที่หลักการ SOLID บางส่วนหรือทั้งหมดไม่ได้ยืมตัวเองเพื่อทำความสะอาดรหัสหรือไม่?

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

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

  1. ใช่มีหลักการออกแบบของ OOP ที่ขัดแย้งกับ SOLID บางส่วน
  2. ใช่มีหลักการออกแบบของ OOP ที่ขัดแย้งกับ SOLID อย่างสมบูรณ์

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

ชั้นเรียนเล็ก

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

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

ทุกวันนี้ฉันพบว่ามีความสมดุลระหว่างความเรียบง่ายของบางสิ่งกับจำนวนสิ่งที่มีและจำนวนปฏิสัมพันธ์ที่ต้องการ ระบบใน ECS มีแนวโน้มที่จะค่อนข้างหนักกับการใช้งานที่ไม่น่ารำคาญในการทำงานกับข้อมูลที่เหมือนPhysicsSystemหรือหรือRenderSystem GuiLayoutSystemอย่างไรก็ตามความจริงที่ว่าผลิตภัณฑ์ที่ซับซ้อนต้องการมีเพียงไม่กี่คนเท่านั้นที่ทำให้ง่ายต่อการถอยกลับและเหตุผลเกี่ยวกับพฤติกรรมโดยรวมของ codebase ทั้งหมด มีบางอย่างอยู่ที่นั่นซึ่งอาจแนะนำว่ามันอาจเป็นความคิดที่ไม่ดีที่จะพึ่งพาด้านข้างของคลาสที่น้อยลงและเป็นกลุ่ม (ยังคงแสดงความรับผิดชอบเอกพจน์เนื้อหา) ถ้านั่นหมายถึงคลาสที่น้อยกว่าในการรักษาและเหตุผล ระบบ.

การติดต่อ

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

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

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

ป้อนคำอธิบายรูปภาพที่นี่

... ถึงสิ่งนี้ที่มีเพียงระบบที่มีฟังก์ชั่นการทำงาน (ตอนนี้ส่วนประกอบสีน้ำเงินเป็นเพียงข้อมูลและตอนนี้นี่คือแผนภาพการมีเพศสัมพันธ์):

ป้อนคำอธิบายรูปภาพที่นี่

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


ฉันชอบความแตกต่างระหว่างการโต้ตอบและการแต่งงานกัน แม้ว่าแผนภาพการโต้ตอบแรกของคุณจะสับสน มันเป็นกราฟระนาบดังนั้นไม่จำเป็นต้องมีลูกศรข้าม
D Drmmr

2

หลักการของ SOLID นั้นดี แต่ KISS และ YAGNI ให้ความสำคัญในกรณีที่เกิดความขัดแย้ง วัตถุประสงค์ของ SOLID คือการจัดการความซับซ้อน แต่ถ้าการใช้ SOLID เองทำให้โค้ดซับซ้อนขึ้นก็จะทำให้วัตถุประสงค์นั้นเสียไป เพื่อยกตัวอย่างหากคุณมีโปรแกรมขนาดเล็กที่มีเพียงไม่กี่คลาสเท่านั้นการใช้ DI การแยกอินเตอร์เฟส ฯลฯ อาจช่วยเพิ่มความซับซ้อนโดยรวมของโปรแกรมได้เป็นอย่างดี

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


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

1
หาก KISS และ YAGNI ให้ความสำคัญกับคุณเสมอคุณควรยังคงเข้ารหัสใน 1 และ 0 แอสเซมเบลอร์เป็นอย่างอื่นที่ผิดพลาดได้ ไม่มี KISS และ YAGNI ชี้ให้เห็นสองในหลาย ๆ ค่าใช้จ่ายในการออกแบบ ต้นทุนนั้นควรจะสมดุลกับผลประโยชน์ของงานออกแบบใด ๆ เสมอ SOLID มีประโยชน์ที่ในบางกรณีค่าใช้จ่าย ไม่มีวิธีง่ายๆในการบอกเมื่อคุณข้ามเส้นไป
candied_orange

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

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

1
@JacquesB - จริง และ OCP นั้นเป็นหัวใจสำคัญของ YAGNI ไม่ว่าคุณจะประสบความสำเร็จคุณต้องออกแบบจุดขยายเพื่อเปิดใช้งานการปรับปรุงในภายหลัง การหาจุดสมดุลที่เหมาะสมระหว่างสองอุดมคติคือ ... หากิน
จูลส์

1

จากประสบการณ์ของฉัน: -

คลาสที่มีขนาดใหญ่นั้นยากต่อการดูแลมากขึ้นเมื่อพวกมันใหญ่ขึ้น

ชั้นเรียนขนาดเล็กนั้นง่ายต่อการบำรุงรักษาและความยากลำบากในการบำรุงรักษาคอลเล็กชั่นของชั้นเรียนขนาดเล็กจะเพิ่มขึ้นตามจำนวนเลขคณิต

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


0

ฉันมักจะพบว่ามันยากที่จะวาดเส้นแบ่งระหว่าง 'S' ของทึบและ (อาจจะล้าสมัย) ต้องให้วัตถุมีความรู้ทั้งหมดของตัวเอง

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

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

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

นอกจากนั้นการหาชื่อที่ดีสำหรับชั้นเรียนนั้นไม่ใช่เรื่องง่ายเสมอไป

ดังนั้นฉันไม่แน่ใจว่าการเป็น 'S' เป็นความคิดที่ดีเสมอ

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