การติดตาม SOLID นำไปสู่การเขียนเฟรมเวิร์กบนสุดของสแต็คเทคโนโลยีหรือไม่


70

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

โดยทั่วไปฉันได้ฝึกการเขียนโปรแกรม 2 โหมด - การสร้างสิ่งที่ถามผ่านข้อกำหนดและ KISS (การเขียนโปรแกรมทั่วไป) มากขึ้นหรือน้อยลงหรือการสร้างตรรกะบริการและอื่น ๆ ที่ใช้ซ้ำทั่วไปและนำกลับมาใช้ใหม่ได้ .

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

นี่เป็นสิ่งที่ดูเหมือนว่าเป็นเรื่องธรรมดาในโลกของ Java Enterprise ที่ให้ความรู้สึกราวกับว่าคุณกำลังออกแบบเฟรมเวิร์กของคุณเองบน J2EE หรือ Spring ดังนั้นมันจึงเป็น UX ที่ดีกว่าสำหรับนักพัฒนาแทนที่จะมุ่งเน้นที่ UX สำหรับผู้ใช้


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

1
คุณทำให้มันฟังดูคล้ายกับหลักการของ SOLID ที่แสดงถึงการลงทุนครั้งใหญ่และงานพิเศษมากมาย มันไม่ได้เป็นฟรีจริง และมันอาจจะช่วยให้คุณหรือคนอื่นลงทุนมากในอนาคตเพราะมันทำให้รหัสของคุณง่ายต่อการบำรุงรักษาและขยาย คุณไปถามคำถามเช่น "เราควรทำการบ้านของเราหรือทำให้ลูกค้ามีความสุข?" สิ่งเหล่านี้ไม่ใช่การแลกเปลี่ยน
Martin Maat

1
@MartinMaat ฉันคิดว่า SOLID ในรูปแบบที่รุนแรงยิ่งกว่านั้นแสดงถึงการลงทุนครั้งใหญ่ กล่าวคือ ซอฟต์แวร์องค์กร นอกเหนือจากซอฟต์แวร์ระดับองค์กรคุณจะมีเหตุผลเพียงเล็กน้อยที่จะแยกแยะ ORM, สแต็คเทคโนโลยีหรือฐานข้อมูลของคุณเนื่องจากมีโอกาสที่ดีมากที่คุณจะติดกับกองซ้อนที่คุณเลือก ในความหมายเดียวกันโดยผูกตัวเองกับกรอบเฉพาะฐานข้อมูลหรือออมคุณกำลังทำลายหลักการ SOLID เพราะคุณเป็นคู่กับกองซ้อนของคุณ ความยืดหยุ่นในระดับนั้นจาก SOLID นั้นไม่จำเป็นสำหรับงานส่วนใหญ่
Igneous01

1
ดูเพิ่มเติมภายในแพลตฟอร์มผล
Maxpm

1
การเปลี่ยนรหัสส่วนใหญ่ให้เป็นสิ่งที่กรอบไม่ได้ฟังดูน่ากลัวเลย มันจะกลายเป็นเรื่องที่น่ากลัวถ้ามันกลายเป็นเรื่องของวิศวกรรมมากเกินไป แต่กรอบงานสามารถน้อยที่สุดและให้ความเห็นได้ ฉันไม่แน่ใจว่านี่จะเป็นผลลัพธ์ที่หลีกเลี่ยงไม่ได้ในการติดตาม SOLID หรือไม่ แต่เป็นผลลัพธ์ที่เป็นไปได้และฉันคิดว่าคุณควรยอมรับ
Konrad Rudolph

คำตอบ:


84

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

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

มอบความยืดหยุ่นที่ผู้พัฒนารายอื่นอาจต้องการ

แทนที่จะให้ความยืดหยุ่นในการพัฒนาอื่น ๆจริงต้องเร็วที่สุดเท่าที่พวกเขาต้องการมันแต่ไม่ได้ก่อนหน้านี้

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

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

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


23
ประเด็นการโต้แย้งเพิ่มเติม: รอจนกว่าคุณจะมี 3 กรณีการใช้งานที่คุณเห็นตรรกะเดียวกันก่อนที่จะทำการเปลี่ยนรหัสของคุณเพื่อนำมาใช้ซ้ำ หากคุณเริ่มต้นการปรับโครงสร้างด้วย 2 ชิ้นเป็นเรื่องง่ายที่จะจบลงในสถานการณ์ที่ความต้องการที่เปลี่ยนแปลงหรือกรณีการใช้งานใหม่กลายเป็นการทำลายสิ่งที่คุณทำ เก็บ refactors ไว้ที่สิ่งต่าง ๆ ด้วยกรณีการใช้งานที่เหมือนกัน: 2 ส่วนประกอบอาจมีรหัสเดียวกัน แต่ทำสิ่งที่แตกต่างกันโดยสิ้นเชิงและถ้าคุณรวมส่วนประกอบเหล่านั้นคุณจะสิ้นสุดการเชื่อมโยงตรรกะนั้นซึ่งอาจทำให้เกิดปัญหาภายหลังบรรทัด
Nzall

8
โดยทั่วไปฉันเห็นด้วยกับสิ่งนี้ แต่รู้สึกว่ามันเน้นไปที่แอป "one-off" มากเกินไป: คุณเขียนโค้ดมันใช้งานได้ดี อย่างไรก็ตามมีแอพจำนวนมากที่มี "การสนับสนุนเป็นเวลานาน" คุณอาจเขียนรหัสและอีก 2 ปีต่อมาข้อกำหนดทางธุรกิจจะเปลี่ยนไปดังนั้นคุณต้องปรับเปลี่ยนรหัส ตามเวลานั้นรหัสอื่น ๆ จำนวนมากอาจขึ้นอยู่กับมัน - ในกรณีนั้นหลักการของ SOLID จะทำให้การเปลี่ยนแปลงง่ายขึ้น
อาร์ชมิทซ์

3
"ก่อนที่เราจะพยายามเขียนโค้ดที่ใช้ซ้ำได้เราควรเขียนโค้ดที่ใช้งานได้" - ฉลาดมาก!
เกรแฮม

10
อาจเป็นเรื่องที่น่าสังเกตว่าการรอจนกว่าคุณจะมีกรณีใช้งานจริงจะทำให้รหัส SOLID ของคุณดีขึ้นเพราะการทำงานในสมมุติฐานนั้นยากมากและคุณมีแนวโน้มที่จะคาดเดาสิ่งที่ต้องการในอนาคต โครงการของเรามีหลายกรณีที่สิ่งต่าง ๆ ได้รับการออกแบบให้มีความยืดหยุ่นและมีความยืดหยุ่นสำหรับความต้องการในอนาคต ... ยกเว้นความต้องการในอนาคตกลายเป็นสิ่งที่ไม่มีใครคิดในเวลาดังนั้นเราทั้งคู่จึงต้องปรับโครงสร้างและมีความยืดหยุ่นเป็นพิเศษ ยังไม่ต้องการ - ซึ่งต้องได้รับการดูแลอย่างต่อเนื่องเมื่อเผชิญกับการปรับสภาพหรือทิ้ง
KRyan

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

49

จากประสบการณ์ของฉันเมื่อเขียนแอพคุณมีสามตัวเลือก:

  1. เขียนโค้ดเพียงเพื่อตอบสนองความต้องการ
  2. เขียนรหัสทั่วไปที่คาดการณ์ข้อกำหนดในอนาคตรวมถึงการปฏิบัติตามข้อกำหนดปัจจุบัน
  3. เขียนโค้ดที่ตอบสนองความต้องการปัจจุบันเท่านั้น แต่ในทางที่เปลี่ยนแปลงได้ง่ายเพื่อตอบสนองความต้องการอื่น ๆ

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

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

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

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


หนึ่งในคำตอบที่ฉันโปรดปรานในเว็บไซต์นี้!
TheCatWhisperer

ฉันไม่แน่ใจว่าคุณสรุปได้อย่างไรว่า 1) ทดสอบได้ยากกว่า 3) ยากกว่าที่จะทำการเปลี่ยนแปลงแน่นอน แต่ทำไมคุณจึงทดสอบไม่ได้ หากมีสิ่งใดซอฟต์แวร์หนึ่งที่มีใจเดียวกันนั้นง่ายต่อการทดสอบกับความต้องการมากกว่าซอฟต์แวร์ทั่วไป
นาย Lister

@MrLister ทั้งสองจับมือกัน 1. ยากต่อการทดสอบมากกว่า 3 เพราะคำจำกัดความหมายถึงมันไม่ได้เขียนว่า "ในแบบที่ง่ายต่อการเปลี่ยนแปลงในภายหลังเพื่อตอบสนองความต้องการอื่น ๆ "
Mark Booth

1
0; IMVHO คุณกำลังตีความผิด (แม้ว่าจะเป็นวิธีทั่วไป) วิธีการทำงานของ 'O' (เปิด - ปิด) ดูตัวอย่างเช่นcodeblog.jonskeet.uk/2013/03/15/… - แม้แต่ใน codebases ขนาดเล็กมันยังเพิ่มเติมเกี่ยวกับการมีหน่วยของโค้ดในตัวเอง (เช่นคลาส, โมดูล, แพ็คเกจ, อะไรก็ตาม) ที่สามารถทดสอบแยกและเพิ่มได้ / ลบออกตามต้องการ ตัวอย่างหนึ่งดังกล่าวจะเป็นชุดของวิธีการยูทิลิตี้ - โดยไม่คำนึงถึงวิธีการรวมกลุ่มของพวกเขาพวกเขาควรจะ 'ปิด' คืออยู่ในตัวเองและ 'เปิด' เช่นขยายได้ในบางวิธี
vaxquis

BTW แม้กระทั่งลุง Bob ก็ไปถึงจุดนั้น: “ หมายความว่า [open-closed] หมายความว่าคุณควรพยายามทำให้โค้ดของคุณอยู่ในตำแหน่งเช่นนั้นเมื่อพฤติกรรมเปลี่ยนไปในทิศทางที่คาดหวังคุณไม่จำเป็นต้องกวาด เปลี่ยนเป็นโมดูลทั้งหมดของระบบ เป็นการดีที่คุณจะสามารถเพิ่มพฤติกรรมใหม่โดยการเพิ่มรหัสใหม่และการเปลี่ยนแปลงรหัสเก่าน้อยหรือไม่มีเลย” <- สิ่งนี้ใช้กับแอปพลิเคชันขนาดเล็กได้อย่างชัดเจนหากพวกเขาตั้งใจจะแก้ไขหรือแก้ไข (และ IMVHO โดยปกติจะเป็นเช่นนั้นโดยเฉพาะเมื่อเกี่ยวข้องกับการแก้ไขหัวเราะ
หึ ๆ

8

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

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

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

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

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


โหมดการเขียนโปรแกรม 2 โหมด - การสร้างสิ่งที่ถามมากขึ้นหรือน้อยลงผ่านข้อกำหนดและ KISS (การเขียนโปรแกรมทั่วไป) หรือการสร้างตรรกะทั่วไปและนำกลับมาใช้ซ้ำได้บริการ ฯลฯ ที่ให้ความยืดหยุ่นที่นักพัฒนาคนอื่นอาจต้องการ

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

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

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

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

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


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

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

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

สมมติว่าคุณสามารถสร้างแอปพลิเคชันได้ใน 4 สัปดาห์และคุณสามารถสร้างแอปพลิเคชันได้อย่างถูกต้องใน 6 สัปดาห์ ตั้งแต่แรกเห็นอาคารที่ดูดีขึ้น ลูกค้าได้รับใบสมัครได้เร็วขึ้นและ บริษัท ต้องใช้เวลาน้อยลงในค่าจ้างนักพัฒนา ชนะ / ชนะใช่ไหม

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

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

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

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

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

การลงทุนเวลาพิเศษในการฝึกฝนที่ดีคือการลงทุนในอนาคต ข้อผิดพลาดในอนาคตและการเปลี่ยนแปลงจะง่ายขึ้นมากเมื่อ codebase ที่มีอยู่สร้างขึ้นบนแนวปฏิบัติที่ดี มันจะจ่ายเงินปันผลหลังจากที่มีการเปลี่ยนแปลงเพียงสองหรือสามครั้ง


1
นี่เป็นคำตอบที่ดี แต่ฉันควรชี้แจงว่าฉันไม่ได้บอกว่าเราละทิ้งแนวทางปฏิบัติที่ดี แต่เราจะทำตาม 'แนวปฏิบัติที่ดี' ในระดับใด เป็นการดีหรือไม่ที่จะทำให้ ORM ของคุณเป็นนามธรรมในทุกโครงการเพราะคุณอาจต้องเปลี่ยนมันเพื่อใช้ในภายหลัง? ฉันไม่คิดอย่างนั้นมีบางระดับของการแต่งงานกันฉันยินดีที่จะยอมรับ (เช่นฉันผูกติดอยู่กับกรอบภาษา ORM ฐานข้อมูลที่เลือก) ถ้าเราทำตาม SOLID ถึงระดับหัวรุนแรงเราจะใช้กรอบงานของเราเองเหนือกองที่เลือกหรือไม่?
Igneous01

คุณกำลังปฏิเสธประสบการณ์ของ OP ในฐานะ "การเข้าใจผิด" ไม่สร้างสรรค์
max630

@ max630 ฉันไม่ได้ปฏิเสธ ฉันใช้เวลาส่วนหนึ่งของคำตอบที่อธิบายว่าทำไมการสังเกตของ OP นั้นถูกต้อง
Flater

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

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

7

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

  • KISS เป็นสาระสำคัญของหลักการความรับผิดชอบแบบS ingle
  • ไม่มีสิ่งใดในปากกาO / หลักการปิด (อย่างน้อยที่สุดเท่าที่ฉันเข้าใจ - ดูJon Skeet ) ที่ขัดกับการเขียนโค้ดเพื่อทำสิ่งใดสิ่งหนึ่งได้ดี (ในความเป็นจริงยิ่งเน้นรหัสแน่นมากขึ้นส่วนที่สำคัญ "ปิด" จะกลายเป็น)
  • L iskov ชดเชยหลักการไม่ได้บอกว่าคุณต้องปล่อยให้คนระดับชั้นย่อยชั้นเรียนของคุณ มันบอกว่าถ้าคุณคลาสย่อยคลาสของคุณคลาสย่อยของคุณควรทำตามสัญญาของซูเปอร์คลาสของพวกเขา นั่นเป็นเพียงการออกแบบที่ดี OO (และถ้าคุณไม่มีคลาสย่อยใด ๆ มันจะไม่มีผล)
  • KISS ยังเป็นสาระสำคัญของหลักการแยกส่วนI nterface
  • D ependency ผกผันหลักการเป็นเพียงคนเดียวที่ฉันสามารถดูจากระยะไกลใช้ แต่ฉันคิดว่ามันเป็นกันอย่างแพร่หลายเข้าใจผิดและยุ้ย ไม่ได้หมายความว่าคุณต้องฉีดทุกอย่างด้วย Guice หรือ Spring มันหมายถึงว่าคุณควรจะนามธรรมที่เหมาะสมและไม่ขึ้นอยู่กับรายละเอียดการใช้งาน

ฉันยอมรับว่าฉันไม่ได้คิดในแง่ของตัวเองเพราะฉันเข้ามาในโรงเรียนเขียนโปรแกรมของGang of FourและJosh Bloch ไม่ใช่โรงเรียน Bob Martin แต่ฉันคิดว่าถ้าคุณคิดว่า "SOLID" = "เพิ่มเลเยอร์ให้กับกองเทคโนโลยีมากขึ้น" คุณกำลังอ่านผิด


PS อย่าขายผลประโยชน์ของ "UX ที่ดีกว่าสำหรับนักพัฒนา" สั้น ๆ รหัสใช้เวลาส่วนใหญ่ในการบำรุงรักษา นักพัฒนาก็คือคุณ


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

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

4
@ Igneous01 การใช้ตรรกะนั้นคุณอาจละทิ้ง getters และ setters ตามที่คุณสามารถสร้าง class แยกต่างหากสำหรับตัวแปร setter ทุกตัวและอีกตัวหนึ่งสำหรับ getter แต่ละตัว IE: class A{ int X; int Y; } class A_setX{ f(A a, int N) { a.X = N; }} class A_getX{ int f(A a) { return X; }} class A_setY ... etc.ฉันคิดว่าคุณกำลังมองจากมุมมองของเมตาด้วยการอ้างสิทธิ์ในโรงงานของคุณ การกำหนดค่าเริ่มต้นไม่ใช่ปัญหาของโดเมน
แอรอน

@Aaron นี่ ผู้คนสามารถใช้ SOLID เพื่อสร้างข้อโต้แย้งที่ไม่ดี แต่นั่นไม่ได้หมายถึงการทำสิ่งที่ไม่ดี = "ติดตาม SOLID"
David Moles
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.