การโง่เพื่อให้ได้ผลผลิตที่ดีกว่า


112

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

if(xxx) {
    doSomething();
}

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

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

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

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

ฉันมักจะรู้สึกไม่พอใจกับผลลัพธ์ของฉันมาก - รหัสที่ดีที่สามารถทำได้ A นั้นแย่กว่ารหัสที่ไม่ดีที่สามารถทำ A, B, C และ D ได้

วิธีนี้มีแนวโน้มที่จะทำให้กำไรสุทธิเป็นบวกสำหรับโครงการซอฟต์แวร์หรือเสียเวลาหรือไม่?


141
ฉันจะดูแข็งของคุณและคุณ rasie YAGNI และ KISS
JK

16
บูมเฮดช็อต
Robert S.

16
ปัญหาของ "over-engineering" บางครั้งเป็นการรวมตัวกันของกระบวนการจับความต้องการที่ไม่ทำงาน หากคุณกำลังดิ้นรนกับ "what-if's" จากนั้นตอบคำถามด้วยตัวคุณเองโดยไม่ต้องมีปฏิสัมพันธ์กับผู้มีส่วนได้เสีย / ลูกค้านั่นจะทำให้คุณอยู่ในตำแหน่งทำนายอนาคต บางทีใช้ความพยายามนั้นและนำกลับไปสู่การทำความเข้าใจกับข้อกำหนดที่ดีกว่าก่อนที่จะนำความซับซ้อนมาสู่โค้ดมากขึ้น?
แองเจโล

4
อาจเป็นเพียงฉัน แต่ฉันจะพิจารณาว่า "โง่" ทำให้ลูกค้า / นายจ้างใช้จ่ายเงินเพื่อมีบางอย่างที่พวกเขาไม่ได้ร้องขอ / ต้องการ: S
Thomas Bonini

2
มันแทบจะเป็นไปไม่ได้เลยที่จะเพิ่มฟีเจอร์ในอนาคตเมื่อจำเป็นจริงๆ คุณไม่ได้รับอะไรเลยโดยทำมันตอนนี้
Hardwareguy

คำตอบ:


153

รหัสที่ดีที่สามารถทำได้ A นั้นแย่กว่ารหัสที่ไม่ดีที่สามารถทำ A, B, C, D ได้

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

ดังนั้น:

รหัสที่ดีที่สามารถทำได้เพียง A (แต่มันทำสิ่งหนึ่งที่ง่ายและสะอาด) คือดีกว่ารหัสที่ไม่ดีที่สามารถทำ A, B, C, D (ซึ่งบางครั้งอาจจำเป็นในอนาคต)


87
+1 สำหรับ "โดยทั่วไปเราจะแย่มากในการทำนายอนาคต" ผู้ใช้มักจะถาม E :)
Michał Piaskowski

1
+1 ไม่สามารถตกลงกันได้อีก ฉันเพิ่งเสร็จสิ้นการทำงานที่ บริษัท และฉันจะพิจารณาบทเรียนนี้สำคัญที่สุดที่ฉันได้เรียนรู้
Wipqozn

4
@ Michałนั่นเป็นการคาดการณ์หรือไม่? ;-)
PéterTörök

10
แม้ว่าพวกเขาจะขอให้คุณ D พวกเขาอาจจะมีรูปแบบทางจิตที่แตกต่างกันและจะขอ D ที่แตกต่างกันเล็กน้อยซึ่ง abstractions ของคุณไม่สนับสนุน ...
Chris Burt-Brown

"หากไม่เข้าใจปัญหาอย่างสมบูรณ์อาจเป็นการดีที่สุดที่จะไม่ต้องแก้ปัญหาเลย" หรือ "อย่าเพิ่มฟังก์ชั่นใหม่เว้นแต่ว่าผู้ดำเนินการไม่สามารถกรอกใบสมัครจริงได้หากไม่มี" ใช้ที่นี่ Via en.wikipedia.org/wiki/X_Window_System#Principles
nwahmaet

87

เรื่องเล็ก ๆ น้อยเวลา:

ฉันมีนักพัฒนาสองคนที่ทำงานให้ฉันซึ่งโน้มตัวไปทางวิศวกรรมมากเกินไปในลักษณะนี้

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

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

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

ดังนั้นอย่า

คุณต้องการให้โค้ดของคุณเรียบง่ายที่สุดเท่าที่จะทำได้ (และไม่ง่ายกว่านี้) การจัดการ 'maybes' ไม่ได้ทำให้เรื่องง่ายขึ้นถ้าคุณเดาว่าผิดคุณจะต้องทำให้โค้ดซับซ้อนขึ้นโดยที่ไม่ได้รับสิ่งใดเลย


10
+1 สำหรับง่ายที่สุด แต่ไม่ง่ายกว่า
Julian

33
"นักออกแบบรู้ว่าเขาบรรลุความสมบูรณ์แบบไม่ใช่เมื่อไม่มีอะไรเหลือให้เพิ่ม แต่เมื่อไม่มีอะไรเหลือให้นำออกไป" อองตวนเดอแซง-Exupery
Arkh

หลีกเลี่ยงการทำซ้ำเช่นภัยพิบัติและคุณจะไม่ผิดไปไกล
เควิน

@arkh ... ฉันจะใช้คำพูดเดียวกัน: P
Michael Brown

6
ฉันจะใช้วิธีนี้: โค้ดทุกบรรทัดมีค่าใช้จ่ายสูง ดังนั้นลดค่าใช้จ่ายด้วยการย่อโค้ดให้เล็กที่สุด การลบรหัสที่ไม่จำเป็นนั้นมีประสิทธิภาพ (อาจมีประสิทธิผลมากกว่า) การเขียนรหัสใหม่
Kristopher Johnson

26

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

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

ฉันชอบที่จะปฏิบัติตามวิธีการสามขั้นตอนง่าย ๆ นี้

  • ในการผ่านครั้งแรกให้ใช้งานได้
  • ในรอบที่สองให้ทำความสะอาด
  • ในรอบที่สามทำให้เป็นของแข็ง

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

ตัวอย่าง: คุณต้องเขียนบรรทัดข้อความอย่างง่ายไปยังคอนโซล ครั้งแรกที่สิ่งนี้เกิดขึ้น Console.WriteLine () ก็ใช้ได้ จากนั้นคุณกลับมาที่รหัสนี้หลังจากข้อกำหนดใหม่ยังสั่งให้เขียนบรรทัดเดียวกันไปยังบันทึกผลลัพธ์ ในตัวอย่างง่ายๆนี้อาจไม่มีรหัส "คัดลอก / วาง" ซ้ำ ๆ (หรืออาจมี) ซ้ำ ๆ แต่คุณยังสามารถทำการล้างพื้นฐานบางอย่างอาจแยกวิธีหรือสองเพื่อหลีกเลี่ยงการดำเนินการ IO inlining ตรรกะทางธุรกิจลึก . จากนั้นคุณกลับมาอีกครั้งเมื่อไคลเอ็นต์ต้องการเอาต์พุตข้อความเดียวกันกับไพพ์ที่มีชื่อสำหรับเซิร์ฟเวอร์การมอนิเตอร์ ตอนนี้รูทีนการแสดงผลนี้เป็นเรื่องใหญ่ คุณกำลังออกอากาศข้อความเดิมสามวิธี นี่คือตัวอย่างตำราเรียนของอัลกอริทึมที่จะได้ประโยชน์จากรูปแบบคอมโพสิต พัฒนาส่วนต่อประสาน IWriter แบบเรียบง่ายด้วยวิธีเขียน () ใช้อินเทอร์เฟซนั้นเพื่อสร้างคลาส ConsoleWriter, FileWriter และ NamedPipeWriter และอีกครั้งหนึ่งเพื่อสร้างคลาสผสม "MultiWriter" จากนั้นแสดงการพึ่งพา IWriter ในชั้นเรียนของคุณตั้งค่าคอมโพสิต MultiWriter กับนักเขียนสามคนจริงและเสียบเข้า ตอนนี้มันค่อนข้างจะแข็ง จากจุดนี้เมื่อใดก็ตามที่ข้อกำหนดกำหนดว่าเอาต์พุตควรไปที่ใดก็ได้ใหม่คุณเพิ่งสร้าง IWriter ใหม่และเสียบเข้ากับ MultiWriter โดยไม่จำเป็นต้องแตะรหัสการทำงานที่มีอยู่


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

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

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

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

กระบวนการที่ดีจริงๆ: ใช้งานได้ดีสะอาดเป็นของแข็ง ฉันสงสัยว่าสิ่งที่เป็นข้อพิสูจน์นี้คือ "อย่าพยายามสร้างสิ่งใด ๆ โดยไม่ต้องต้นแบบต้นแบบถูกแฮ็กก่อน"
Steve Bennett

17

รหัสที่ดีที่สามารถทำได้ A นั้นแย่กว่ารหัสที่ไม่ดีที่สามารถทำ A, B, C, D ได้

1) มีรหัสที่ทำในสิ่งที่ควรทำเท่านั้น

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

2) หากคุณวางแผนรหัสของคุณให้ทำ A, B, C และ D ลูกค้าจะถามคุณในที่สุด E

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

ผมขอแนะนำให้คุณอ่านหนังสือที่ดี: โปรแกรมเมอร์ศาสตร์ มันจะเปิดใจและสอนสิ่งที่คุณควรทำและสิ่งที่คุณไม่ควรทำ

นอกจากนี้Code Completeยังเป็นแหล่งข้อมูลที่เต็มไปด้วยข้อมูลที่มีประโยชน์ซึ่งนักพัฒนาซอฟต์แวร์ทุกคน (ไม่เฉพาะโปรแกรมเมอร์) ควรอ่าน


12

เวลามากฉันต้องเขียนโค้ดง่ายๆฉันคิดเกี่ยวกับอนาคต

บางทีนี่อาจเป็นปัญหา

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

หากคุณต้องการเขียนโค้ดสามบรรทัดคุณต้องสร้างส่วนต่อประสานใหม่และคลาสสองคลาส คุณจะได้รับรหัสที่จะบำรุงรักษายากและอ่านยากเพียงเพราะสำหรับรหัสบรรทัดที่มีประโยชน์ทุกครั้งคุณมีโค้ดสองบรรทัดที่คุณไม่ต้องการ ไม่นับเอกสารประกอบ XML การทดสอบหน่วย ฯลฯ

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

ข้อควรจำ: codebase ที่ใหญ่ขึ้นหมายถึงการบำรุงรักษาที่มากขึ้น อย่าเขียนรหัสเพิ่มเติมเมื่อคุณสามารถหลีกเลี่ยงได้

วิธีการของคุณยังเป็นอันตรายในด้านอื่น ๆ :

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

  • เมื่อทำการดีบั๊กมันจะง่ายกว่าไหมถ้ามีการติดตามสแต็กเล็ก ๆ หรือคุณต้องการอ่านหลายสิบบรรทัดเพื่อหาว่าอะไรถูกเรียกโดยอะไร

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


"คลาสกึ่งว่างเปล่าหลายสิบคลาส" มีข้อเสียเพิ่มเติมที่มีวัสดุไม่เพียงพอที่จะเข้าใจว่าคลาสเหล่านี้ดีสำหรับอะไร
gnasher729

5

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


3

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


3

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

ฉันพบเจอกับสิ่งนี้ตลอดเวลาในทุกงานที่ฉันเคยมีมันเหมือนคำสาปที่ฉันไม่สามารถหลบหนีได้ วัฒนธรรม บริษัท เป็นเสมอเส้นทางของด้านมืดและ hacks รวดเร็ว / การแก้ไขจะผลักดันออกคุณสมบัติใหม่และอ้อนวอนและเสียงร้องของ refactoring และการเขียนรหัสของฉันถูกต้องตกอยู่ในหูหูหนวกถ้ามันไม่ได้นำไปสู่การเลิกจ้างของฉัน " พยายามที่จะเปลี่ยนแปลงสิ่งต่าง ๆ "(ไม่มีเรื่องตลกที่ฉันเคยเกิดขึ้นมาหลายครั้งเพราะฉันต้องการที่จะแนะนำรูปแบบการออกแบบ

ความจริงที่น่าเศร้าก็คือบ่อยครั้งที่วิธีที่โง่เขลา / ด้านมืดเป็นวิธีที่คุณต้องเหยียบคุณต้องทำให้แน่ใจว่าจะเหยียบเบา ๆ ฉันได้ช้าและเศร้าตระหนักว่าโปรแกรมเมอร์ที่เข้าใจที่ถูกต้องวิธีการเขียนซอฟต์แวร์คือต่อไปนี้ SOLID โดยใช้รูปแบบการออกแบบ SoC เชื่อฟัง ฯลฯ จะมากน้อยกว่า hacks clueless ที่จะเขียนifคำสั่งเพื่อแก้ไขข้อผิดพลาดและ เมื่อมีข้อบกพร่องเกิดขึ้นเพียงเพิ่มลงในคำสั่งนั้นแทนที่จะคิดว่า "อาจจะมีวิธีที่ดีกว่าในการทำเช่นนี้" และ refactoring รหัสที่จะขยายได้อย่างถูกต้อง


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

@Coder พยายามอย่าคิดว่าสถาปัตยกรรมไม่สามารถเปลี่ยนแปลงได้ตลอดเวลา มันสามารถและไม่
Ricky Clarkson

1
Wayne M ฉันสามารถเห็นอกเห็นใจกับสถานการณ์การทำงานของคุณ อยู่กับแรง :)
Jennifer S

3

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

ฉันจะดูสถานการณ์ของคุณและถามคำถามเหล่านี้:

  1. รหัสนี้เป็นภารกิจที่สำคัญหรือไม่และจะมีเสถียรภาพมากขึ้นหากฉันกำหนดรหัสใหม่หรือไม่ ในการพูดการผ่าตัดการช่วยชีวิตนี้เป็นการฟื้นฟูหรือเป็นเพียงวิชาเลือกและเป็นเครื่องสำอางหรือไม่?

  2. ฉันกำลังพิจารณา refactoring code ที่เรากำลังจะเปลี่ยนในอีก 6 เดือนหรือไม่

  3. ฉันยินดีที่จะใช้เวลาในการจัดทำเอกสารการออกแบบและเหตุผลของฉันสำหรับนักพัฒนาในอนาคตหรือไม่

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

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


3

ใน Stroustrups รุ่นที่สอง 'ภาษาการเขียนโปรแกรม C ++' (ฉันไม่มีหน้าว่าง) ฉันอ่าน

อย่าเพิ่มรหัสในสถานที่

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

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

แต่คุณต้องถามคำถาม YAGNI: มันคุ้มหรือไม่ มันจะมีประโยชน์จริง ๆ หรือไม่ การมีประสบการณ์หมายความว่าคุณจะไม่ค่อยผิดและในฐานะมือใหม่มักจะผิดมากกว่า

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

การแก้ปัญหาไม่ใช่สิ่งนี้หรือสิ่งนั้น แต่ต้องคิดเกี่ยวกับมัน :)


2

"รหัสที่ดีที่สามารถทำได้เพียง A นั้นแย่กว่ารหัสที่ไม่ดีที่สามารถทำ A, B, C และ D"

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

ใน 'โครงการ IT' ถ้าคุณตั้งโปรแกรมที่ดีมันจะทำงานได้อย่างราบรื่นตลอดอายุการใช้งานของโครงการ - ซึ่งอาจไม่ทำงานนานกว่า 5 หรือ 10 ปีจากนั้นสถานการณ์ทางธุรกิจอาจจะล้าสมัยและโครงการใหม่ / ERP ผลิตภัณฑ์อาจมีการแทนที่ ในช่วงอายุการใช้งาน 5/10 ปีนี้เว้นแต่ว่า htere เป็นข้อบกพร่องในรหัสของคุณจะไม่มีใครสังเกตเห็นว่ามันมีอยู่จริงและความคิดที่ดีที่สุดของคุณจะไม่มีใครสังเกตเห็น! (เว้นแต่ว่าคุณเก่งในการเป่าแตรเสียงแตรของคุณเอง!)

มีไม่มากนักที่จะได้รับโอกาสในการเขียนโปรแกรม 'Windows Ctl + Alt + Del' และผู้ที่ได้รับโอกาสนั้นอาจไม่ได้ตระหนักถึงศักยภาพของรหัสในอนาคต!


1

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


1

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

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


1
ในกรณีส่วนใหญ่คุณจะไม่มีเวลาพิเศษสำหรับการเปลี่ยนโครงสร้าง - นั่นอาจเป็นเหตุผลหลักสำหรับสิ่งเหล่านี้ "เราไม่สามารถใช้สิ่งนี้ได้โดยไม่ต้องใช้งานอีกครั้ง" ;-) คุณทำอย่างถูกวิธีตั้งแต่ต้น หรือคุณทำผิดวิธีตลอดเวลา
Andrey Agibalov

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

1

เมื่อได้เห็นการออกแบบทั่วไปก่อนกำหนดที่ไม่สอดคล้องกับข้อกำหนดที่เกิดขึ้นจริงในภายหลังฉันจึงกำหนดกฎสำหรับฉัน:

สำหรับความต้องการสมมุติเพียงเขียนโค้ดสมมุติฐาน

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


0

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

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


0

ฉันคิดว่า over-engineering มักจะดูเหมือนจากความไม่ปลอดภัยเกี่ยวกับการเขียนรหัส หลักการและรูปแบบนามธรรมทั้งหมดควรได้รับการปฏิบัติเป็นเครื่องมือที่จะช่วยคุณ สิ่งที่เกิดขึ้นบ่อยครั้งคือพวกเขาได้รับการปฏิบัติเหมือนเป็นมาตรฐาน

ฉันเชื่อว่าโปรแกรมเมอร์มักจะอยู่ในตำแหน่งที่ดีกว่าในการตัดสินใจว่าจะให้นามธรรมมากกว่าสัจพจน์

ส่วนที่เหลือได้รับการกล่าวโดย KeithS


ฉันคิดว่าวิธีหนึ่งที่จะได้ความปลอดภัยของตัวเองเกี่ยวกับการเขียนโค้ดคือการเข้ารหัสในฐานะที่เป็นรากของระบบลินุกซ์ ถ้าคุณพิมพ์จำใจบูมคุณจะต้อง reimage VM สอนนิสัยดี ๆ ทุกชนิดอย่างรวดเร็วจริง ๆ ตรวจสอบให้แน่ใจกล่องของคุณอาศัยอยู่ในอินเทอร์เน็ตจริงและให้แน่ใจว่าคุณดูบันทึก (ssh, http) มันสนุกจริงๆ!
Christopher Mahan

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

0

ถามตัวเองว่าข้อดีของการออกแบบที่ดีคืออะไร:

  • เข้าใจง่ายขึ้น
  • รักษาง่ายขึ้น
  • แบบพกพา
  • การเข้าพักมีประโยชน์มาเป็นเวลานาน
  • ง่ายต่อการเพิ่มคุณสมบัติใหม่

ทีนี้ลองถามตัวเองดูว่าการเพิ่มเลเยอร์ abstractions ทั้งหมดนั้นจะเพิ่มไปยังจุดใด ๆ ที่กล่าวถึงข้างต้นหรือไม่ ถ้ามันไม่ได้คุณกำลังทำมันผิด

หากคุณสามารถเพิ่มคุณสมบัติใหม่ได้โดยเพิ่มรหัส 3 บรรทัดดังนี้:

if (condition()) {
  doSomething()
}

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

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

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

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