หลักการเขียนโปรแกรม SOLID


43

เมื่อเวลาผ่านไปฉันสามารถเข้าใจสองส่วนของSOLID - "S" และ "O"

“ O” - ฉันเรียนรู้หลักการแบบเปิดด้วยความช่วยเหลือของรูปแบบการสืบทอดและกลยุทธ์

“ S” - ฉันเรียนรู้หลักการความรับผิดชอบเดี่ยวขณะเรียนรู้ ORM (ตรรกะการคงอยู่ถูกพรากไปจากวัตถุโดเมน)

ในทำนองเดียวกันภูมิภาค / ภารกิจที่ดีที่สุดในการเรียนรู้ส่วนอื่น ๆ ของ SOLID (“ L”,“ I” และ“ D”) คืออะไร?

อ้างอิง

  1. msdn - อันตรายจากการละเมิดหลักการ SOLID ใน C #
  2. channel9 - การนำหลักการ SOLID ไปใช้ใน. NET / C #
  3. หลักการของ OOPS (หลักการที่เป็นของแข็ง)

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

3
ผู้ทำแผนที่นั้นดีสำหรับการแยกความกังวลไม่ใช่หลักการความรับผิดชอบเดี่ยว ดูโพสต์นี้programmers.stackexchange.com/questions/155628/…สำหรับการสนทนาเกี่ยวกับความแตกต่าง
Doc Brown เมื่อ

ตัวอย่างโลกแห่งความจริงblog.gauffin.org/2012/05/…
LCJ

1
@JarrodRoberson ครับว่าทำไมพวกเขาจะเรียกอย่างระมัดระวังเพื่อเป็นแนวทาง อย่าลืมหลักการอื่น ๆ ที่เหลือ: adamjamesnaylor.com/2012/11/12/… (ทั้งหมด 11 รายการ)
Adam Naylor

2
ลิงค์ของ @AdamNaylor ตอนนี้ 404ing ถูกย้ายไปที่adamjamesnaylor.com/post/ …
mattumotu

คำตอบ:


54

ฉันอยู่ในรองเท้าของคุณสองสามเดือนที่ผ่านมาจนกระทั่งฉันพบบทความที่มีประโยชน์มาก

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

เป็นแหลมในความคิดเห็นนั้นก็เป็นอีกรูปแบบไฟล์ PDF อ่านดีมาก - ของปาโบล SOLID การพัฒนาซอฟต์แวร์

นอกจากนี้ยังมีบางหนังสือที่ดีที่อธิบายถึงหลักการที่มั่นคงในรายละเอียดมากขึ้น - หนังสือดีใน SOLID การพัฒนาซอฟต์แวร์

แก้ไขและแสดงความคิดเห็นของการสรุปสั้น ๆ สำหรับแต่ละหลักการ:

  • “ S” - หลักการความรับผิดชอบเดี่ยวถูกขับเคลื่อนโดยความต้องการของธุรกิจเพื่อให้เกิดการเปลี่ยนแปลง “ เหตุผลเดียวในการเปลี่ยนแปลง” ช่วยให้คุณเข้าใจว่าแนวคิดใดที่แยกกันอย่างมีเหตุผลควรจัดกลุ่มเข้าด้วยกันโดยพิจารณาจากแนวคิดและบริบททางธุรกิจแทนที่จะเป็นแนวคิดทางเทคนิคเพียงอย่างเดียว In another wordsฉันเรียนรู้ว่าแต่ละชั้นควรมีความรับผิดชอบเดียว ความรับผิดชอบคือการทำภารกิจที่ได้รับมอบหมายให้สำเร็จ

  • “ O” - ฉันเรียนรู้ Open Open Principle และเริ่มที่จะ“ ชอบการแต่งมากกว่าการสืบทอด” และเป็นเช่นนั้นเลือกชั้นเรียนที่ไม่มีวิธีการเสมือนและอาจปิดผนึก แต่ขึ้นอยู่กับ abstractions สำหรับการขยาย

  • “ L” - ฉันเรียนรู้หลักการทดแทน Liskov ด้วยความช่วยเหลือของรูปแบบ Repository สำหรับจัดการการเข้าถึงข้อมูล

  • “ ฉัน” - ฉันเรียนรู้เกี่ยวกับหลักการแยกอินเทอร์เฟซโดยการเรียนรู้ว่าลูกค้าไม่ควรถูกบังคับให้ใช้อินเทอร์เฟซที่ไม่ได้ใช้ (เช่นผู้ให้บริการสมาชิกใน ASP.NET 2.0) ดังนั้นอินเตอร์เฟสไม่ควรมี“ ความรับผิดชอบมาก”
  • “D” - ผมได้เรียนรู้เกี่ยวกับการอ้างอิงผกผันหลักการและเริ่มที่จะรหัสที่ง่ายต่อการเปลี่ยนแปลง เปลี่ยนง่ายขึ้นหมายถึงต้นทุนการเป็นเจ้าของโดยรวมลดลงและการบำรุงรักษาสูงขึ้น

เนื่องจากทรัพยากรที่มีประโยชน์จาก CodePlex ถูกกล่าวถึงในความคิดเห็นการอ้างอิงจะรวมอยู่ในSOLID ด้วยตัวอย่าง

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


3
ฉันพบคอลเลกชันต่อไปนี้ของบทความที่มีประโยชน์มาก: lostechies.com/wp-content/uploads/2011/03/ …
Scroog1

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

3
ตั้งแต่บทความที่หายไปถูกกล่าวถึงที่นี่นอกจากนี้ยังมีsolidexamples.codeplex.comนี้(ขึ้นอยู่กับ Lostechies)
เฟดเดอร์มืด

2
ฉันเป็นหนึ่งในผู้ร่วมให้ข้อมูลของ Pablos eBook ฉันดีใจที่ผู้คนยังคงพบว่ามันมีประโยชน์ :)
Sean Chambers

1
+1000000 ถ้าฉันทำได้สำหรับบทสรุปของคุณเกี่ยวกับหลักการ Open-Closed - ทุกคนทำผิดพลาดและคิดว่ามันเกี่ยวกับการสืบทอด
AlexFoxGill

11

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


2
+1 นี่มันจริงมาก คุณไม่จำเป็นต้องปฏิบัติตาม (imo) บางครั้งเข้มงวดเกินไป 'การทดสอบหน่วยควรทดสอบสิ่งเดียว' กฎ: ถ้าคุณไม่สามารถหาชุดทดสอบที่ดีสำหรับชั้นเรียนได้ภายในไม่กี่นาที ละเมิด I และ D และอาจเป็นไปได้ว่าคนที่เหลือเป็นอัลเบ็ทเช่นกัน
stijn

8

หลักการทดแทน Liskovโดยพื้นฐานแล้วไม่อนุญาตให้คุณใช้การสืบทอดการใช้งานมากเกินไป: คุณไม่ควรใช้การสืบทอดเพียงเพื่อนำโค้ดกลับมาใช้ใหม่ (มีองค์ประกอบสำหรับสิ่งนี้)! โดยการปฏิบัติตาม LSP คุณสามารถมั่นใจได้ว่ามี "is-a สัมพันธ์" ระหว่างซูเปอร์คลาสและคลาสย่อยของคุณ

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

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

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

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


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