ในกรณีใดรหัสน้อยไม่ดีขึ้น? [ปิด]


55

ฉันเพิ่งปรับปรุงรหัสบางส่วนในที่ทำงานเมื่อเร็ว ๆ นี้และฉันคิดว่าฉันทำงานได้ดี ฉันลดโค้ด 980 บรรทัดไปที่ 450 และลดจำนวนคลาสลงครึ่งหนึ่ง

เมื่อแสดงสิ่งนี้ต่อเพื่อนร่วมงานของฉันบางคนไม่เห็นด้วยว่านี่เป็นการปรับปรุง

พวกเขากล่าวว่า - "บรรทัดที่น้อยกว่าของรหัสไม่จำเป็นต้องดีกว่า"

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

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


145
ขนาดรหัสถูกวัดในเวลาที่คุณต้องอ่านและเข้าใจไม่ใช่เส้นหรือจำนวนตัวอักษร
Bergi

13
คำถามของคุณเป็นลายลักษณ์อักษรกว้างเกินไป แนะนำให้เขียนใหม่เกี่ยวกับการเปลี่ยนแปลงเฉพาะที่คุณทำแทน
jpmc26

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

65
มีเว็บไซต์แลกเปลี่ยนทั้งกองที่ทุ่มเทให้กับการตอบคำถามของคุณคือ: codegolf.stackexchange.com :)
Federico Poloni

10
ความซ้ำซ้อนที่เป็นไปได้ของณ จุดใดกะทัดรัดไม่มีคุณธรรมอีกต่อไป?
Bob Tway

คำตอบ:


124

คนผอมไม่จำเป็นต้องมีสุขภาพดีกว่าคนที่มีน้ำหนักเกิน

เรื่องราวของเด็ก 980 บรรทัดนั้นง่ายต่อการอ่านมากกว่าวิทยานิพนธ์ฟิสิกส์ 450 เส้น

มีคุณสมบัติมากมายที่กำหนดคุณภาพของรหัสของคุณ บางคนจะคำนวณก็เช่นCyclomatic ซับซ้อนและHalstead ซับซ้อน อื่น ๆ มีการกำหนดอย่างเข้มงวดมากขึ้นเช่นการทำงานร่วมกัน , ความสามารถในการอ่าน, ความเข้าใจ, ความสามารถในการขยาย, ความทนทาน, ความถูกต้อง, การจัดทำเอกสารด้วยตนเอง, ความสะอาด, การทดสอบและอื่น ๆ อีกมากมาย

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

แยกเป็นชิ้นยาวของรหัสลงในวิธีการเล็ก ๆอาจจะเป็นอันตรายในขณะที่มันอาจจะเป็นประโยชน์

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


1
@PiersyP เพียงแค่ FYI ซึ่งเป็นหนึ่งในแนวทางที่ฉันได้รับการสอนเกี่ยวกับการปรับโครงสร้างที่ดีคือเราควรเห็นความซับซ้อนของวงจรลดลงเป็นรากที่สองของสิ่งที่มันเคยเป็นมา
MA Hanin

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

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

1
เพียงเพราะมันไม่จำเป็นไม่ได้หมายความว่ามันไม่มีคุณค่า
Chris Wohlert

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

35

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

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

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


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

18

ข้อความที่อ้างถึงบ่อยครั้งคือ Albert Einstein อยู่ในใจ:

ทำทุกอย่างให้ง่ายที่สุด แต่ไม่ง่ายกว่านี้

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

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

ถ้าฉันบอกว่าvar x = 2 + 2;มันชัดเจนทันทีว่าxควรเป็นจำนวนเต็ม แต่ถ้าฉันบอกว่าvar foo = value.Response;มันชัดเจนน้อยกว่าทั้งที่fooเป็นตัวแทนและคุณสมบัติและความสามารถของมัน แม้ว่าคอมไพเลอร์สามารถอนุมานได้ง่ายมันทำให้ความพยายามในการรับรู้มากขึ้นในคน

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


7
varตัวอย่างไม่ดีโดยเฉพาะอย่างยิ่งหนึ่งในความเรียบง่ายเพราะส่วนใหญ่เวลาอ่านและทำความเข้าใจรหัสเกี่ยวข้องกับการหาพฤติกรรมในระดับหนึ่งของนามธรรมดังนั้นการรู้ประเภทที่เกิดขึ้นจริงของตัวแปรเฉพาะมักจะไม่ได้เปลี่ยนแปลงอะไร (มันเท่านั้น ช่วยให้คุณเข้าใจ abstractions ที่ต่ำกว่า) ตัวอย่างที่ดีกว่าคือโค้ดง่าย ๆ หลายบรรทัดที่บีบให้เป็นคำสั่งที่ซับซ้อนเดียวเช่น if ((x = Foo()) != (y = Bar()) && CheckResult(x, y)) ใช้เวลาในการค้นหาและรู้ประเภทxหรือyไม่ช่วยอะไรเลยแม้แต่น้อย
Ben Cottrell

15

รหัสที่ยาวขึ้นอาจจะง่ายต่อการอ่าน ปกติแล้วจะตรงกันข้าม แต่มีข้อยกเว้นมากมาย - บางข้อสรุปในคำตอบอื่น ๆ

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

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

4
+1 สำหรับ 'Pecritenc' และบทสรุปที่ดีมากของการคัดค้านล่วงหน้าที่ควรได้รับการพิจารณาก่อนการเตรียมการล่วงหน้า

1
และ +1 สำหรับ 'ความสามารถในการขยาย' - ฉันคิดว่ารหัสดั้งเดิมอาจมีฟังก์ชั่นหรือคลาสที่มีไว้สำหรับใช้ในโครงการในอนาคตดังนั้นบทคัดย่ออาจดูเหมือนซ้ำซ้อนหรือไม่จำเป็น แต่ในบริบทของโปรแกรมเดียว
Darren Ringer

นอกจากนี้รหัสที่เป็นปัญหาอาจไม่ได้เป็นรหัสที่มีความสำคัญดังนั้นควรพิจารณาให้ทรัพยากรด้านวิศวกรรมสูญเปล่าเพื่อทำความสะอาด
Erik Eidt

@nocomprende มีเหตุผลอะไรบ้างที่คุณใช้ preconable, preconsidered และ prefactoring? วิธีการคล้ายกับ Pecritenc อาจจะ?
Milind R

@MilindR เป็นไปได้ไหมว่าการตั้งเป้าหมายความชอบหรือความชอบส่วนตัว? หรืออาจจะไม่มีเหตุผลเลยก็ได้การรวมตัวกันของจักรวาลของปัจจัยร่วมทำให้เกิดภาวะสมรู้ร่วมคิดที่สับสน ไม่มีความคิดจริงๆ แล้วคุณล่ะ?

1

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

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

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

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


3
"คลาสปู่ย่าตายาย"! ลังเล! เพียงระวังคลาสอาดัมและอีฟ (และคลาสของพระเจ้าแน่นอน) ก่อนหน้านี้มันไม่มีรูปแบบและเป็นโมฆะ

1

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

ดังนั้น,

enum OPTION1 { OPTION1_OFF, OPTION1_ON };
enum OPTION2 { OPTION2_OFF, OPTION2_ON };

void doSomething(OPTION1, OPTION2);

เป็น verbose มากขึ้นกว่า

void doSomething(bool, bool);

อย่างไรก็ตาม

doSomething(OPTION1_ON, OPTION2_OFF);

สามารถอ่านได้มากกว่า

doSomething(true, false);

คอมไพเลอร์ควรสร้างรหัสเดียวกันสำหรับทั้งสองดังนั้นจึงไม่มีอะไรที่จะได้รับโดยใช้แบบฟอร์มที่สั้นกว่า


0

ฉันว่าการทำงานร่วมกันอาจเป็นปัญหา

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

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

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


0
  • เมื่อรหัสน้อยลงจะไม่ทำงานเช่นเดียวกับรหัสเพิ่มเติม การปรับโครงสร้างใหม่เพื่อความเรียบง่ายนั้นเป็นสิ่งที่ดี แต่คุณต้องระวังอย่าทำให้พื้นที่ที่มีปัญหาตรงตามที่แก้ปัญหานี้มากเกินไป โค้ด 980 บรรทัดอาจรองรับกรณีมุมมากกว่า 450
  • เมื่อรหัสน้อยลงก็ไม่ได้ล้มเหลวอย่างที่ควรจะเป็นเช่นเดียวกับรหัสเพิ่มเติม ฉันได้เห็นงาน "ref *** toring" สองสามรายการที่ทำบนโค้ดเพื่อลบรายการลองและจับข้อผิดพลาดอื่น ๆ ที่ไม่จำเป็น ผลลัพธ์ที่หลีกเลี่ยงไม่ได้คือแทนที่จะแสดงกล่องโต้ตอบพร้อมข้อความที่ดีเกี่ยวกับข้อผิดพลาดและสิ่งที่ผู้ใช้สามารถทำได้แอปขัดข้องหรือ YSODed
  • เมื่อรหัสน้อยลงสามารถบำรุงรักษา / ขยายได้น้อยกว่ารหัสเพิ่มเติม การปรับโครงสร้างใหม่เพื่อความกระชับของรหัสมักจะลบการสร้างรหัส "ไม่จำเป็น" ในความสนใจของ LoC ปัญหาคือการสร้างโค้ดเหล่านั้นเช่นการประกาศอินเตอร์เฟสแบบขนานวิธีการแยก / คลาสย่อย ฯลฯ เป็นสิ่งจำเป็นหากรหัสนี้จำเป็นต้องทำมากกว่าที่เป็นอยู่ในปัจจุบันหรือทำแตกต่างกัน ในที่สุดการแก้ปัญหาบางอย่างที่ปรับแต่งให้เข้ากับปัญหาเฉพาะอาจไม่ทำงานเลยถ้าคำจำกัดความปัญหาเปลี่ยนไปเพียงเล็กน้อย

    ตัวอย่างหนึ่ง; คุณมีรายการจำนวนเต็ม จำนวนเต็มแต่ละค่าเหล่านี้มีค่าซ้ำกันในรายการยกเว้นค่าหนึ่ง อัลกอริทึมของคุณต้องค้นหาค่าที่ไม่ได้รับการจับคู่ วิธีแก้ปัญหากรณีทั่วไปคือการเปรียบเทียบทุกหมายเลขกับทุก ๆ หมายเลขอื่นจนกว่าคุณจะพบหมายเลขที่ไม่มีผู้ล่อในรายการซึ่งเป็นการดำเนินการ N ^ 2 ครั้ง คุณสามารถสร้างฮิสโตแกรมโดยใช้ hashtable ได้ แต่มันไม่มีประสิทธิภาพด้านอวกาศ อย่างไรก็ตามคุณสามารถทำให้เป็นเชิงเส้นเวลาและพื้นที่คงที่ได้โดยใช้การดำเนินการ XOR แบบ bitwise XOR ทุกจำนวนเต็มเทียบกับ "ผลรวม" (เริ่มต้นด้วยศูนย์) และท้ายที่สุดผลรวมสะสมจะเป็นค่าของจำนวนเต็มที่ไม่ได้รับการจับคู่ สง่างามมาก. จนกว่าความต้องการจะเปลี่ยนแปลงและอาจมี unpaired มากกว่าหนึ่งหมายเลขในรายการหรือจำนวนเต็มรวมศูนย์ ตอนนี้โปรแกรมของคุณจะส่งคืนขยะหรือผลลัพธ์ที่คลุมเครือ (ถ้ามันคืนค่าศูนย์นั่นหมายความว่าองค์ประกอบทั้งหมดถูกจับคู่หรือว่าองค์ประกอบที่ไม่ได้รับการจับคู่นั้นมีค่าเป็นศูนย์?) ดังกล่าวเป็นปัญหาของการใช้งาน "ฉลาด" ในการเขียนโปรแกรมในโลกแห่งความจริง

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

0

รหัสคอมพิวเตอร์จำเป็นต้องทำหลายสิ่ง รหัส "minimalist" ที่ไม่ทำสิ่งเหล่านี้ไม่ใช่รหัสที่ดี

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

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

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


หน้าที่อยู่ในสายตาของคนดู

-2

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


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

1
@alephzero ว้าวฉันชอบที่จะเห็นรหัสนั้นจะต้องเป็นเพียง Cray Cray

@ alphzero คอมไพเลอร์ที่ดีสามารถทำอะไรได้มากมาย แต่น่าเสียดายที่ไม่ใช่ทุกอย่าง ด้านที่สว่างคือสิ่งเหล่านั้นคือสิ่งที่ทำให้การเขียนโปรแกรมน่าสนใจ!
Hans Janssen

2
@alephzero รหัสการคูณเมทริกซ์ที่ดีไม่เพียง แต่ช่วยลดเวลา (เช่นลดลงด้วยปัจจัยคงที่) โดยใช้อัลกอริทึมที่แตกต่างกันโดยสิ้นเชิงกับความซับซ้อนเชิงซีมโทติคที่แตกต่างกันเช่นอัลกอริธึม Strassenคือ O (n ^ 2.8) มากกว่า O (n ^ 3)
Arthur Tacca
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.