สิ่งใดที่กริ่งสัญญาณเตือนทันทีเมื่อดูรหัส? [ปิด]


98

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

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

ฉันจะเริ่มต้นด้วยสิ่งที่ง่าย:

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


61
บางครั้งฉันพบคนที่ใส่ความคิดเห็นรหัสตรวจสอบและพูดว่า "ฉันอาจต้องการมันอีกในอนาคต - ถ้าฉันลบมันตอนนี้ฉันจะเสีย" ฉันต้องตอบโต้ด้วย "Er, ... แต่นั่นคือสิ่งที่ควบคุมแหล่งที่มาสำหรับ"
talonx

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

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

8
ฉันปล่อยให้สิ่งที่ "อาจจะใช้" ในสำหรับ 1 กระทำแล้วถ้าสิ่งที่ไม่ทำลายลงหรือไม่พบความต้องการมันจะถูกลบออกในการกระทำต่อไป
พอลนาธาน

24
อืมมม printf("%c", 7)โดยทั่วไปจะส่งสัญญาณเตือนภัยให้ฉัน ;)

คำตอบ:


128
/* Fuck this error */

โดยทั่วไปมักพบในtry..catchบล็อกไร้สาระก็มีแนวโน้มที่จะดึงดูดความสนใจของฉัน /* Not sure what this does, but removing it breaks the build */เพียงเกี่ยวกับเช่นเดียวกับ

อีกสองสิ่ง:

  • ifคำสั่งที่ซับซ้อนหลายระดับซ้อนกัน
  • Try-catch blocks ที่ใช้เพื่อกำหนดลอจิกโฟลว์เป็นประจำ
  • ฟังก์ชั่นที่มีชื่อทั่วไปprocess, data, change, rework,modify
  • รูปแบบการค้ำยันหกหรือเจ็ดแบบใน 100 บรรทัด

หนึ่งที่ฉันเพิ่งค้นพบ:

/* Stupid database */
$conn = null;
while(!$conn) {
    $conn = mysql_connect("localhost", "root", "[pass removed]");
}
/* Finally! */
echo("Connected successfully.");

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


19
ถ้าเพียงฉันสามารถโหวตได้ 6 ครั้ง! ตัวอย่างที่ดีทั้งหมด ฉันยังไม่ชอบความคิดเห็นที่หยิ่งยโส / ตลก (โดยเฉพาะถ้าพวกเขารวมถึงการสบถ) - มันอาจจะน่าขบขันเล็กน้อยในครั้งแรกที่คุณอ่านพวกเขา แต่ได้รับเก่ามาก
FinnNk

5
ฉันชอบตัวอย่างของคุณแม้ว่าฉันจะบอกว่าในบริบทบางอย่างซ้อนกันหลายถ้างบหลีกเลี่ยงไม่ได้ ด้วยตรรกะทางธุรกิจจำนวนมากรหัสอาจทำให้เกิดความสับสนเล็กน้อย แต่หากธุรกิจของตัวเองสับสนเริ่มต้นด้วยการทำให้รหัสง่ายขึ้นก็จะเป็นการจำลองกระบวนการให้แม่นยำน้อยลง ดังที่ Einstein กล่าวว่า: "สิ่งต่าง ๆ ควรเรียบง่ายที่สุดเท่าที่จะเป็นไปได้
Morgan Herlocker

2
@Prof Plum - คุณให้ตัวอย่างอะไรได้บ้าง มักจะเป็นทางเลือกที่ซ้อนกันหลาย ๆ ถ้าเป็นวิธีการแบ่งออกเป็นหลายวิธี ผู้พัฒนาเยาวชนมักจะหลีกเลี่ยงสิ่งนี้ราวกับว่ามันเป็นที่ต้องการน้อยกว่าของ แต่โดยปกติเมื่อกดพวกเขาพูดว่า "ถ้าทำมันในเส้นที่น้อยลง" มันทำให้ใครบางคนมีความมั่นใจใน OOP เพื่อก้าวเข้ามาและเตือนพวกเขาว่ามีเส้นน้อยลง! = รหัสที่ดีขึ้น
STW

2
@STW นั่นเป็นประเด็นที่ดีอย่างไรก็ตามฉันจะบอกว่ามันขึ้นอยู่กับว่ารังอยู่ลึกแค่ไหน แน่นอนฉันจะยอมรับว่าสิ่งที่มากกว่าสามรังลึกมักจะต้องการ refactoring เพราะจะได้ขนสวย การทำประกันภัยอ้างอิงเป็นตัวอย่างที่ดีที่การทำรังหลายแบบสามารถจำลองโลกแห่งความเป็นจริงได้ค่อนข้างดี โดยมีข้อยกเว้นสำหรับอัตรา / เบี้ยประกันภัยบางอย่างคู่มือจะอ่านอะไรอย่าง "ถ้าเป็นทรัพย์สินและถ้ามันมีอัตราขั้นต่ำต่ำกว่า 5.6 และถ้าอยู่ใน NC และถ้ามีเรืออยู่ในสถานที่ให้ทำเช่นนั้นและ ดังกล่าว." ด้วยตัวเลือกอื่น ๆ
Morgan Herlocker

4
@ Josh ถ้า "พวกเขา" เป็นเพื่อนร่วมงานฉันจะไตร่ตรองว่าทำไมคุณถึงไม่พูดว่า "พวกเรา" ...

104

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

ฉันเคยนับว่าไม่มีความคิดเห็นเป็นธงสีแดง แต่เมื่อไม่นานมานี้ได้ทำงานกับโค้ดที่ดีมาก ๆ โดยที่ไม่มีความคิดเห็นใดที่ฉันได้ปลดเปลื้องไปแล้ว


1
+1: ฉันเห็นโค้ดบางส่วนจากเพื่อนร่วมงานที่โน้มน้าวตัวเองในฐานะผู้เชี่ยวชาญ linux ผู้เขียนแอปพลิเคชันแบบวนซ้ำอย่างง่าย ๆ เป็นฟังก์ชั่นยาวหนึ่งสิ่งทั้งหมดซ้ำแล้วซ้ำอีกใน main () Yikes
KFro

4
@KFro นั่นคือการเปิดลูป นั่นคือสิ่งที่คอมไพเลอร์ทำตลอดเวลา :) มีประสิทธิภาพมาก!

3
@Thorbjorn: บางครั้งคุณต้องช่วยคอมไพเลอร์หน่อย ท้ายที่สุดคุณเป็นมนุษย์ที่ฉลาดและเขาเป็นแค่คอมพิวเตอร์โง่
yatima2975

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

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

74

รหัสที่พยายามแสดงให้เห็นว่าโปรแกรมเมอร์ฉลาดอย่างไรแม้ว่ามันจะไม่เพิ่มมูลค่าที่แท้จริง:

x ^= y ^= x ^= y;

12
ว้าวนั่นเป็นสิ่งที่อ่านได้ง่ายกว่ามากswap(x, y);
JBRWilkinson

8
ถ้า x และ y เป็นตัวชี้และการมอบหมายนี้เกิดขึ้นในช่วงระยะเวลาที่เหมาะสมพอสมควรมันก็จะทำลายตัวรวบรวมขยะแบบอนุรักษ์นิยมเช่น Boehm GC
SingleNegationElimination

12
อย่างไรก็ตามโค้ดนี้ไม่ได้กำหนดไว้ใน C และ C ++ เนื่องจากมีการเปลี่ยนแปลงหลายครั้งโดยไม่มีจุดลำดับที่เข้ามาแทรกแซง
fredoverflow

9
เมื่อมองดูสิ่งเดียวที่นึกได้คืออิโมติคอน:^_^
เดเรีย

62
  • ฟังก์ชันบรรทัด 20,000 (พูดเกินจริง) ฟังก์ชั่นใด ๆ ที่ใช้เวลามากกว่าสองหน้าจอจำเป็นต้องมีแฟคตอริ่งใหม่

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

  • ตัวแปรที่ไม่อธิบาย, ไม่ใช่ตัวแปร, หรือตัวแปรที่ไม่อธิบายมากเกินไป สิ่งเหล่านี้ทำให้การอนุมานสิ่งที่เกิดขึ้นจริงเป็นปริศนา


9
ฉันมักจะ จำกัด ฟังก์ชั่นไว้ที่ 1 หน้าจอทุกครั้งที่ทำได้
Matt DiTrolio

20
1 หน้าจอยืดออกได้ ฉันเริ่มรู้สึกสกปรกหลังจาก 10 บรรทัดขึ้นไป
Bryan Rowe

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

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

6
@Dominic, @ Péterฉันคิดว่าพวกเราสามคนกำลังพูดในสิ่งเดียวกัน เมื่อมีเหตุผลที่ดีในการแยกรหัสในฟังก์ชั่นที่เล็กกว่าฉันก็ทำได้ สิ่งที่ฉันปฏิเสธคือความสั้นเพื่อประโยชน์ในการออกแบบฟังก์ชั่น คุณรู้ไหมว่า call stack ที่ยาวเกินกว่าความต้องการสามเท่า แต่อย่างน้อยฟังก์ชั่นเหล่านั้นจะสั้น ฉันควรดีบั๊กฟังก์ชั่นสูงที่ทำสิ่งหนึ่งได้ดีและชัดเจนกว่าการไล่ล่าเส้นทางการดำเนินการผ่านฟังก์ชั่นที่ถูกล่ามโซ่โหลที่แต่ละคนเรียกจากหน้าที่ก่อนหน้านี้เท่านั้น
Dan Ray

61
{ Let it Leak, people have good enough computers to cope these days }

สิ่งที่แย่กว่านั้นคือจากห้องสมุดเชิงพาณิชย์!


32
นี่ไม่ใช่เสียงระฆังปลุก มันแทบเตะคุณระหว่างขา
Steven Evers

15
ลูกสาวเป็นคนติดยา ใครสนใจอย่างน้อยเธอก็จะไม่อ้วน :: ถอนหายใจ ::
Evan Plaice

17
เมื่อฉันพบว่าตัวเองตกอยู่ในสถานการณ์ลำบากแม่ buntu ก็มาหาฉัน การพูดคำพูดของภูมิปัญญาปล่อยให้มันรั่วไหล ปล่อยให้มันรั่วไหล .. ปล่อยให้มันรั่วไหล ปล่อยให้มันรั่วไหลปล่อยให้มันรั่วไหล ถ้ามันรั่วเพียงครั้งเดียวมันไม่ใช่ leaaaaaak (ถ้าคุณอ่านมาถึงตอนนี้ +1) ฉันจำเป็นต้องพิจารณา decaf
Tim Post

13
"เมื่อถึงกำหนดเส้นตายอย่างรวดเร็วการรั่วไหลคือทุกสิ่งที่ฉันเห็นบางคนกระซิบว่า 'เขียนใน C ...... eeeeee !!!'"
chiurox

9
กาลครั้งหนึ่งมีสองระบบปฏิบัติการ หนึ่งรั่วไหลและล้มเหลวถ้ามันวิ่งมานานกว่า 49 วันอื่น ๆ ที่สมบูรณ์แบบและจะวิ่งไปตลอดกาล หนึ่งเปิดตัวในปี 1995 เพื่อ fanfair ใหญ่และถูกใช้โดยผู้คนนับล้าน - อื่น ๆ ไม่เคยส่งเพราะพวกเขายังคงตรวจสอบว่ามันเป็นข้อผิดพลาดฟรี มีความแตกต่างระหว่างปรัชญาและวิศวกรรม
Martin Beckett

53

ความคิดเห็นที่ละเอียดมากว่าถ้ามีคอมไพเลอร์ภาษาอังกฤษมันจะคอมไพล์และทำงานได้อย่างสมบูรณ์แบบ แต่ก็ไม่ได้อธิบายสิ่งที่โค้ดไม่ได้

//Copy the value of y to temp.
temp = y;
//Copy the value of x to y.
y = x;
//Copy the value of temp to x.
x = temp;

นอกจากนี้ความคิดเห็นเกี่ยวกับรหัสที่สามารถทำได้โดยมีรหัสปฏิบัติตามหลักเกณฑ์พื้นฐานบางอย่าง:

//Set the age of the user to 13.
a = 13;

15
นั่นคือมันเรียกว่าภาษาโคบอล :-)
ออกุสตุส

26
กรณีที่สองไม่ใช่เรื่องเลวร้ายที่สุด ที่แย่ที่สุดคือ: / * ตั้งอายุของผู้ใช้เป็น 13 * / a = 18;
PhiLho

4
@PhiLho - ไม่ยิ่งแย่ไปกว่านั้นคือเมื่อส่วน/ที่*/ขาดหายไปดังนั้นโค้ดทั้งหมดถึงจุดสิ้นสุดของถัดไป*/จะถูกละเว้น โชคดีที่การเน้นไวยากรณ์ทำให้สิ่งเหล่านี้หายากในปัจจุบัน
Steve314

3
แย่ลงอีกครั้งaสำหรับ user_age? จริงๆ?
glasnt

2
ฉันใช้เพื่อรักษาเอกสารมาตรฐานรหัสที่นายจ้างคนก่อนหน้าซึ่งส่วนหนึ่งของการแสดงความคิดเห็นที่เหมาะสม ตัวอย่างเช่นโปรดของฉันมาจาก MSDN:i = i + 1; //increment i
ไมเคิล Itzoe

42

รหัสที่สร้างคำเตือนเมื่อรวบรวม


1
มีตัวเลือกสำหรับการเพิ่มตัวเลือกคอมไพเลอร์ 'คำเตือนทั้งหมดเป็นข้อผิดพลาด' ให้กับ makefile / project
JBRWilkinson

3
ฉันเดาว่าอาจมีประโยชน์หากคุณอยู่ในโครงการที่มีคนหลายคนที่คุณไม่ไว้วางใจ - แม้ว่าฉันจะเข้าร่วมโครงการที่ตั้งค่าตัวเลือกนั้นในตัวเองจะทำให้ฉันกังวลว่าคนอื่น ๆ จะทำได้อย่างไร โปรแกรมเมอร์คือ
Rei Miyasaka

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

13
ฉันอยากจะเกะกะโค้ดของฉันด้วยความเฉื่อยชา(unsigned int)มากกว่าความยุ่งเหยิงของฉันรายการเตือน / ข้อผิดพลาดด้วยคำเตือนที่ไม่เป็นอันตราย ฉันเกลียดที่รายการเตือนจะกลายเป็นจุดบอด นอกจากนี้ยังมีอื่น ๆ อีกมากมายของ PITA อธิบายให้คนอื่น ๆ ทำไมคุณไม่สนใจคำเตือนกว่าก็คือการอธิบายว่าทำไมคุณกำลังทำโยนของธรรมชาติไปints unsigned ints
Rei Miyasaka

บางครั้งคุณต้องทำงานกับ API ที่พ่นข้อผิดพลาดไม่ว่าคุณจะทำอะไร ตัวอย่างคลาสสิกเป็นที่ที่ API ถูกกำหนดในแง่ของสิ่งต่าง ๆ ที่หักจากการออกแบบ (ค่าคงที่ของ ioctl () บางค่าคงเป็นเช่นนั้นและในบางครั้งนักพัฒนาระบบปฏิบัติการยืนยันว่า ออกจากการทดแทนที่ดี (ขอบคุณ Apple)
Donal Fellows

36

ฟังก์ชั่นที่มีตัวเลขในชื่อแทนที่จะมีชื่ออธิบายเช่น:

void doSomething()
{
}

void doSomething2()
{
}

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


ในทำนองเดียวกัน @Parm สำหรับ SQL
เดฟ

2
+1 - เข้าmshtml- มันทำให้ฉันไม่ได้สนใจ :(
Kyle Rozendo

3
ข้อยกเว้นนี้จะเป็นรหัส GUI ตัวอย่างเช่นหากแบบฟอร์มอีเมลหอยทากมีสองที่อยู่ address1 และ address2 เหมาะสมกว่าที่อยู่และ AlternateAddress ป้ายปลอมที่เป็นแบบคงที่เท่านั้นก็เป็นข้อยกเว้นที่สมเหตุสมผลเช่นกัน
Evan Plaice

@Evan - ยุติธรรมเพียงพอแม้ว่าฉันจะสร้างความแตกต่างในการใช้งานได้มากกว่า
Wonko the Sane

1
+1 - ฉันเคยเห็นสิ่งนี้ใช้เป็นวิธีการควบคุมแบบหลอก
EZ Hart

36

หมายเลข Magicหรือ Magic Strings

   if (accountBalance>200) { sendInvoice(...); }

   salesPrice *= 0.9;   //apply discount    

   if (invoiceStatus=="Overdue") { reportToCreditAgency(); }

4
ไม่จริงที่ไม่ดีกับสองที่สองอย่างน้อยมีการอธิบายส่วนลดและ "Overdue" นั้นใช้งานง่าย 200บนมืออื่น ๆ ...
Tarka

9
@Slokun - ใช้งานง่ายไม่ได้เป็นจุดมากไปกว่าการบำรุงรักษาและความเปราะบาง ตัวอย่างเช่นพิจารณาว่าจะเกิดอะไรขึ้นเมื่อการเปลี่ยนแปลงจำนวนส่วนลดและ 0.9 ถูกกำหนดค่าตายตัวในหกแห่ง นอกจากนี้การใช้สตริงแทนค่าคงที่ / enums จะถามถึงปัญหาในภาษาที่มีสตริงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่
JohnFx

+1 ฉันใช้เวลามากเกินไปในการดีบั๊กปัญหาที่เกิดจากบรรทัด 'timeout = 15;' ฝังอยู่ในโปรแกรม
aubreyrhodes

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

36
  • อาจไม่ใช่ระดับที่แย่ที่สุด แต่แสดงระดับผู้ใช้งานอย่างชัดเจน:

    if(something == true) 
  • หากภาษานั้นมีโครงสร้าง for for หรือ iterator ดังนั้นการใช้ a while loop จะแสดงให้เห็นถึงระดับความเข้าใจของผู้ใช้ภาษา:

    count = 0; 
    while(count < items.size()){
       do stuff
       count ++; 
    }
    
    for(i = 0; i < items.size(); i++){
      do stuff 
    }
    //Sure this is not terrible but use the language the way it was meant to be used.
  • การสะกด / ไวยากรณ์ไม่ดีในเอกสาร / ความคิดเห็นกินได้เกือบเท่าโค้ดของตัวเอง เหตุผลนี้เป็นเพราะรหัสมีไว้สำหรับมนุษย์ที่จะอ่านและเครื่องทำงาน นี่คือเหตุผลที่เราใช้ภาษาระดับสูงหากเอกสารของคุณยากที่จะผ่านมันทำให้ฉันมีความคิดเห็นเชิงลบของโค้ดเบสโดยไม่ได้มองมาที่นี่


29

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


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

28

เมื่อให้คะแนนโปรแกรมของนักเรียนบางครั้งฉันสามารถบอกได้ในช่วงเวลา "กะพริบ" - สไตล์ นี่คือเบาะแสทันที:

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

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

เมื่อพิจารณาโค้ดขั้นสูงเพิ่มเติมนี่คือคำเตือนอื่น ๆ ของฉัน:

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

ในแง่ของสไตล์ฉันมักไม่ชอบที่จะเห็น:

  • ความคิดเห็น Javadoc ที่สะท้อนรหัสเท่านั้น

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


ฉันล้มเหลวในการดูว่าการใช้สไตล์จากภาษาหนึ่งในอีกภาษาหนึ่งเป็นข้อผิดพลาดอันยิ่งใหญ่ (2, 4, 8 ช่องว่างต่อการเยื้อง ... ) หากนักเรียนมีรูปแบบอื่น ๆ ที่น่าติดตามไม่มีอะไรผิดปกติกับการเป็นคนที่มีความสอดคล้อง ในฐานะผู้ให้คะแนนคุณเห็นรายการเป็นพันล้านรายการดังนั้นคุณจึงอยู่ฝั่งตรงข้ามของสเปกตรัมนั้น แต่นั่นไม่ใช่เหตุผลที่จะยกเลิกสไตล์ที่แตกต่าง (แต่สอดคล้องกัน) โดยสิ้นเชิง
Nick T

18
ฉันไม่เห็นอะไรผิดปกติกับคลาสที่รวมข้อมูลเพียงอย่างเดียวนั่นคือ structs นั่นคือสิ่งที่ Data Transfer Objects (DTOs) เป็นและสามารถทำให้โค้ดอ่านได้มากกว่าการพูดเช่นการส่งพารามิเตอร์ 20 รายการไปยังวิธีการ
Nemi

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

2
+1 สำหรับสไตล์ที่ไม่สอดคล้องและตัวแบ่งบรรทัดพิเศษ (ฉันเคยเห็นการเยื้องแบบสุ่มไม่มีการเยื้องการสุ่มและการเปลี่ยนแปลงการตั้งชื่อการประชุมและอื่น ๆ - และสิ่งนี้อยู่ในรหัสการผลิต!) หากคุณไม่สามารถที่จะทำให้ถูกต้องได้คุณจะต้องทำอะไรอีก
Dean Harding

1
ฉันมองหาบรรทัดการประกาศของวิธีการเยื้องที่สัมพันธ์กับร่างกายมากเกินไป นี่เป็นสัญญาณที่พวกเขาคัดลอกและวางจากไฟล์ของคนอื่น
Barry Brown

25

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


25

ตัวแปรที่ไม่ได้ใช้อย่างสมบูรณ์โดยเฉพาะอย่างยิ่งเมื่อตัวแปรมีชื่อคล้ายกับชื่อตัวแปรที่ใช้


21

ผู้คนมากมายพูดถึง:

//TODO: [something not implemented]

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

//TODO: [something that is already implemented]

สิ่งที่ต้องทำไม่มีค่าและสับสนหากคุณไม่เคยสนใจที่จะลบออก!


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

1
-1 ความคิดเห็น TODO ใช้ใน MS Visual Studio เพื่อติดตามส่วนต่าง ๆ ของโครงการที่ยังต้องใช้งาน IE, IDE เก็บรายการที่ติดตามสิ่งที่ต้องทำเพื่อให้คุณสามารถคลิกที่พวกเขาได้อย่างง่ายดายและถูกนำไปยังบรรทัดที่สิ่งที่ต้องทำอยู่บนโดยตรง ฉันอยากจะเห็นสิ่งที่ต้องทำวางไว้อย่างชัดเจนเพื่อดูว่ายังคงต้องทำงานอะไรอีก ดูdotnetperls.com/todo
Evan Plaice

3
@Evan Plaice: ว้าวคุณหมายถึง VS IDE รู้จักเมื่อคุณติดตั้งและลบ//TODOความคิดเห็นหรือไม่ น่ากลัว!
JBRWilkinson

4
@Prof Plum ทำไมไม่เพียงสร้างนโยบายที่บุคคลที่รับผิดชอบสิ่งที่ต้องทำใส่ชื่อของพวกเขาในความคิดเห็น ด้วยวิธีนี้หากมีสิ่งที่เหลืออยู่
Evan Plaice

3
วางแผนดีกว่า// TODO ใช้ตัวติดตามบั๊กของคุณนั่นคือสิ่งที่เป็นไปได้!
SingleNegationElimination

20

วิธีที่ต้องให้ฉันเลื่อนลงเพื่ออ่านทั้งหมด


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

9
ในฐานะที่เป็นคำสั่งแบบครอบคลุมจากนั้นฉันไม่เห็นด้วยการเสียเวลาในการปรับโครงสร้างใหม่อย่างต่อเนื่องเพื่อให้ทุกอย่างเหมาะสมกับกฎการเรียกเก็บเงินประเภทนี้จริง ๆ แล้วเพิ่มต้นทุนโดยรวมของโครงการ
ประเภทไม่ระบุตัวตน

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

18
ฉันหงุดหงิดมากขึ้นเมื่อเลื่อนไปทางขวามากกว่าตอนเลื่อนลง ช่องว่างคือ "ฟรี"
Wonko the Sane

4
ฉันต้องการเลื่อนมากกว่าต้องข้ามไฟล์ (หรือหลายไฟล์) เพื่อหาว่าโค้ดทำอะไร
TMN

20

คำสันธานในชื่อเมธอด:

public void addEmployeeAndUpdatePayrate(...) 


public int getSalaryOrHourlyPay(int Employee) ....

ชี้แจงเหตุนี้แหวนระฆังปลุกก็คือว่ามันแสดงให้เห็นวิธีการที่มีแนวโน้มละเมิดหลักการรับผิดชอบเดียว


อืม ... ถ้าชื่อฟังก์ชั่นถูกต้องกำหนดสิ่งที่ฟังก์ชั่นแล้วฉันไม่เห็นด้วย หากวิธีการทำสองสิ่งแยกกันซึ่งจะเป็นการดีกว่าที่จะแยกจากกันฉันอาจเห็นด้วยขึ้นอยู่กับบริบท
Wonko the Sane

2
นั่นคือประเด็น การรวมกันแสดงว่ามีโอกาสมากที่จะทำมากกว่าหนึ่งอย่าง ตามคำถามมันเป็นเพียงสิ่งที่ทำให้ฉันรับรู้ว่ามีบางอย่างผิดปกติ
JohnFx

3
ทีนี้ถ้าคุณต้องเพิ่มพนักงานและอัพเดทอัตราเงินเดือนของพวกเขาในหลาย ๆ ที่ล่ะ? หากวิธีนั้นมีการเรียกสองวิธี ( addEmployee(); updatePayrate();) แสดงว่าฉันไม่คิดว่าเป็นปัญหา
Matt Grande

13

เห็นได้ชัดว่าการเชื่อมโยงซอร์สโค้ด GPL กับโปรแกรมเชิงพาณิชย์และปิด

ไม่เพียง แต่จะสร้างปัญหาทางกฎหมายในทันที แต่จากประสบการณ์ของฉันมันมักจะบ่งบอกถึงความประมาทหรือความไม่สนใจซึ่งจะปรากฏที่อื่นในรหัสเช่นกัน


6
ในขณะที่ประเด็นของคุณยอดเยี่ยมเสียงของคุณไม่จำเป็น
JBRWilkinson

@JBRWilkinson: ขอบคุณคุณถูกต้อง ฉันขอโทษทุกคน
Bob Murphy

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

จุดที่ดี ฉันเขียนโพสต์ใหม่ทั้งหมด ขอบคุณทุกคน.
Bob Murphy

9

ผู้ไม่เชื่อเรื่องภาษา:

  • TODO: not implemented
  • int function(...) { return -1; } (เช่นเดียวกับ "ไม่ใช้งาน")
  • โยนข้อยกเว้นด้วยเหตุผลที่ไม่พิเศษ
  • ในทางที่ผิดหรือการใช้งานที่ไม่สอดคล้องกันของ0, -1หรือnullค่ากลับมาเป็นพิเศษ
  • ยืนยันโดยไม่ต้องแสดงความคิดเห็นที่น่าเชื่อถือบอกว่าทำไมมันไม่ควรล้มเหลว

ภาษาเฉพาะ (C ++):

  • C ++ แมโครเป็นตัวพิมพ์เล็ก
  • ตัวแปร C ++ คงที่หรือทั่วโลก
  • ตัวแปรที่ไม่ได้กำหนดค่าหรือไม่ได้ใช้
  • สิ่งใดก็ตามarray newที่เห็นว่าไม่ปลอดภัย RAII
  • การใช้อาเรย์หรือตัวชี้ใด ๆ ที่เห็นได้ชัดว่าไม่ปลอดภัย printfซึ่งรวมถึง
  • การใช้งานส่วนที่ไม่ได้กำหนดค่าเริ่มต้นของอาร์เรย์

เฉพาะ Microsoft C ++:

  • ชื่อตัวระบุใด ๆ ที่ชนกับมาโครที่กำหนดไว้แล้วโดยไฟล์ส่วนหัวของ Microsoft SDK ใด ๆ
  • โดยทั่วไปการใช้ Win32 API เป็นแหล่งสัญญาณเตือนภัยขนาดใหญ่ เปิด MSDN เสมอและค้นหาอาร์กิวเมนต์ / คำนิยามค่าที่ส่งคืนเมื่อใดก็ตามที่มีข้อสงสัย (แก้ไข)

เฉพาะ C ++ / OOP:

  • การใช้งาน (คลาสคอนกรีต) การสืบทอดที่คลาสพาเรนต์มีทั้งวิธีเสมือนและไม่เสมือนโดยไม่มีความแตกต่างทางแนวคิดที่ชัดเจนระหว่างสิ่งที่ควร / ไม่ควรเป็นเสมือน

18
// สิ่งที่ต้องทำ: แสดงความคิดเห็นต่อคำตอบนี้
johnc

8
ฉันเดาว่า "ผู้ไม่เชื่อเรื่องภาษา" หมายถึง "C / C ++ / Java" ตอนนี้หรือไม่
Inaimathi

+1 "การโยนข้อยกเว้นด้วยเหตุผลที่ไม่ธรรมดา" ไม่สามารถตกลงได้อีก!
billy.bob

2
@Inaimathi - ความคิดเห็นสิ่งที่ต้องทำสตับทำงานยกเว้นการละเมิดความสับสนของซีแมนทิกส์ศูนย์ / โมฆะ / ว่างเปล่าและการตรวจสอบสติที่ไม่มีจุดหมายนั้นมีอยู่ในภาษา OOP ที่จำเป็นทั้งหมดและบางส่วนของภาษาโปรแกรมทั่วไป
Rei Miyasaka

ฉันเชื่อว่ามาโครตัวประมวลผลล่วงหน้า C ในกรณีที่ต่ำกว่านั้นใช้ได้ แต่เฉพาะในกรณีที่พวกเขาประเมินข้อโต้แย้งของพวกเขาเพียงครั้งเดียวและส่งผลให้คำสั่งเดียวเท่านั้น
Joe D

8

สไตล์การเยื้องที่แปลกประหลาด

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


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

1
ฉันหวังว่าคุณจะเหน็บแนม หากมีใครบางคนกำลังเข้ารหัสในลักษณะผิดปกติเช่นนั้นควรตั้งค่าปิดสัญญาณเตือนภัย พวกเขาสามารถเป็นศิลปะได้ตามที่ต้องการ แต่ยัง ... ระฆังปลุก
Ken

2
มีสไตล์ที่ค่อนข้างแปลก (ฉันเชื่อว่าเป็นสไตล์ Utrecht) ที่ฉันพบว่ามีประโยชน์มากแม้ว่าจะเป็นเรื่องแปลกนอก Haskell / ML / F # เลื่อนลงไปที่ "รูปร่างโมดูล": learnyouahaskell.com/making-our-own-types-and-typeclasses สิ่งที่ดีเกี่ยวกับสไตล์นี้คือคุณไม่ต้องแก้ไขตัวคั่นบนบรรทัดก่อนหน้าเพื่อเพิ่มอันใหม่ - ซึ่งฉันมักจะลืมทำ
Rei Miyasaka

@ReiMiyasaka ปลายปีที่เจ็ด แต่ ... สไตล์ Utrecht ทำให้ฉันโกรธจริงๆ ฉันเชื่อว่าเป็นข้อผิดพลาดในข้อกำหนดของ Haskell ที่จะไม่กำหนด "กฎการจัดหน้า" อื่น ๆ ในรายการที่จัดเรียงตามแนวตั้ง ด้วยวิธีนี้ parser สามารถตรวจจับรายการใหม่เพียงแค่ตรวจสอบการเยื้องซึ่งเป็นวิธีที่ทุกคนจัดระเบียบรายการของพวกเขาต่อไป
Ryan Reich

@ RyanReich แปลกเจ็ดปีต่อมาและฉันยังคงชอบมัน ฉันเห็นด้วยแม้ว่า; สำหรับความไม่สะดวกและความล้มเหลวในการทำประโยคทั้งหมด F # ยังอนุญาตให้รายการถูกคั่นด้วยการขึ้นบรรทัดใหม่และการเยื้อง (ในกรณีส่วนใหญ่) ซึ่งทำให้เป็นระเบียบเรียบร้อย
Rei Miyasaka

8

การใช้บล็อคข้อความจำนวนมากแทนที่จะใช้ enums หรือตัวแปรที่กำหนดไว้ทั่วโลก

ไม่ดี:

if (itemType == "Student") { ... }

ที่ดีกว่า:

private enum itemTypeEnum {
  Student,
  Teacher
}
if (itemType == itemTypeEnum.Student.ToString()) { ... }

ที่ดีที่สุด:

private itemTypeEnum itemType;
...
if (itemType == itemTypeEnum.Student) { ... }

หรือดีที่สุด: ใช้ความหลากหลาย
Lstor

8

พารามิเตอร์ที่พิมพ์อ่อนแอหรือคืนค่าตามวิธีการ

public DataTable GetEmployees() {...}

public DateTime getHireDate(DataTable EmployeeInfo) {...}

public void FireEmployee(Object EmployeeObjectOrEmployeeID) {...}

2
+1: ฉันต้องทำงานกับบริการเว็บ "REST" บางอย่างที่ส่งคืนทุกอย่างเป็นตารางหลอก - HTML แม้ว่าคุณจะผ่านสิ่งที่มีข้อผิดพลาดทางไวยากรณ์ที่ชัดเจน ไม่มีอำนาจ? ป้อนข้อมูลขยะสมบูรณ์หรือไม่ เซิร์ฟเวอร์มีความจุเกิน 200 (บวกข้อความในรูปแบบที่น่ากลัวในหนึ่งคอลัมน์หนึ่งตารางแถว) AAaaaaaaaargh!
Donal Fellows

7
  • ผู้ประกอบการที่ประกอบไปด้วยกันหลายคนหงุดหงิดดังนั้นแทนที่จะคล้ายif...elseบล็อกมันกลายเป็นif...else if...[...]...elseบล็อก
  • ชื่อตัวแปรแบบยาวที่ไม่มีขีดล่างหรือ camelCasing ตัวอย่างจากรหัสฉันดึงขึ้นมา:$lesseeloginaccountservice
  • บรรทัดของโค้ดหลายร้อยบรรทัดในไฟล์ที่มีความคิดเห็นเพียงเล็กน้อยและไม่มีเลยและโค้ดนั้นไม่ชัดเจนมาก
  • ifข้อความที่ซับซ้อนมากเกินไป ตัวอย่างจากรหัส: if (!($lessee_obj instanceof Lessee && $lessee_obj != NULL))ซึ่งฉัน chomped ลงไปif ($lessee_obj == null)

7

กลิ่นรหัส: ไม่ปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุด

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

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

สิ่งใดที่กริ่งสัญญาณเตือนทันทีเมื่อดูรหัส?

มีการพูดถึงสิ่งดี ๆ มากมายและโดยทั่วไปดูเหมือนว่าการไม่ปฏิบัติตามวิธีปฏิบัติที่ดีที่สุดคือกลิ่นรหัส

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

ตัวอย่างหนึ่งของแนวปฏิบัติที่ดีที่สุดอาจใช้ curlies กับ if-block ทุกรายการแม้ว่าจะมีเพียงหนึ่งบรรทัด:

if (something) {
    // whatever
}

คุณอาจไม่คิดว่ามันจำเป็น แต่เมื่อเร็ว ๆ นี้ฉันอ่านว่ามันเป็นแหล่งสำคัญของข้อบกพร่อง การใช้วงเล็บยังถูกกล่าวถึงในStack Overflowเสมอและตรวจสอบว่า if-statement มีวงเล็บเป็นกฎในPMDตัววิเคราะห์โค้ดแบบคงที่สำหรับ Java

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


2
นี่อาจเป็นเรื่องหยาบคาย แต่ฉันคิดว่ามันสำคัญกับสิ่งที่คุณเลือกโดยเฉลี่ย ตามที่ฉันเข้าใจแล้ว 50% ของประชากรโลกอยู่ต่ำกว่าค่ามัธยฐาน (ตามคำจำกัดความ); แต่ค่าเฉลี่ยอื่นไม่ทำงานในลักษณะเดียวกัน ตัวอย่างเช่นใช้ประชากร (1, 1, 1, 5) ซึ่งมีค่าเฉลี่ยเลขคณิตของ 2
flamingpenguin

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

@Evan: ใช่คุณพูดถูก ฉันเพิ่มเรื่องนี้อีกเล็กน้อยหวังว่านี่จะช่วยได้
Vetle

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

ความคิดเห็นดีมากแดน! ฉันเพิ่มสองบรรทัดสุดท้ายในคำตอบ
Vetle

6

ความคิดเห็นที่บอกว่า "นี่เป็นเพราะการออกแบบของระบบย่อย froz นั้นเต็มไปด้วยบอร์ก"

ที่ดำเนินต่อไปในย่อหน้าทั้งหมด

พวกเขาอธิบายว่า refactor ต่อไปนี้จำเป็นต้องเกิดขึ้น

แต่ไม่ได้ทำ

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

หากหัวหน้างานคิดว่า j.random โปรแกรมเมอร์ไม่สามารถทำการปรับโครงสร้างใหม่ได้จากนั้นหัวหน้างานควรทำ

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

เรื่องจริง. มันอาจจะเกิดขึ้นกับคุณ.


6

ทุกคนสามารถนึกถึงตัวอย่างที่รหัสควรอ้างถึงไฟล์อย่างถูกต้องตามเส้นทางที่แน่นอน?


1
สกีมา XML มีค่าหรือไม่
Nick T

1
ไฟล์การกำหนดค่าระบบ โดยทั่วไปควรตั้งค่าโดย. / config แต่ก็จำเป็นต้องมีค่าเริ่มต้นจากที่อื่น
eswald

4
/dev/nullและเพื่อน ๆ ก็โอเค แต่ถึงแม้สิ่งที่ต้องการ/bin/bashเป็นผู้ต้องสงสัย - สิ่งที่ถ้าคุณเป็นหนึ่งในบางระบบที่มีบ้า/usr/bin/bash?
Tom Anderson

1
รหัสไคลเอนต์บริการเว็บที่สร้างโดยเครื่องมือ JAX-WS (JBossWS และ Metro อย่างน้อย) มีเส้นทางแบบสัมบูรณ์ที่มีการเดินสายไปยังไฟล์ WSDL (สองครั้ง!) /home/tom/dev/randomhacking/thing.wsdlซึ่งอาจเป็นสิ่งที่ไม่เหมาะสมอย่างดุเดือดเช่น มันเป็นอาชญากรบ้าว่านี่คือพฤติกรรมเริ่มต้น
Tom Anderson

4
เกี่ยวกับ/dev/null: ฉันมีนิสัยเมื่อมีการพัฒนาบน Windows เพื่อให้ปพลิเคชันและ libs c:\devภายใต้ อย่างใดโฟลเดอร์nullจะถูกสร้างขึ้นโดยอัตโนมัติภายในโฟลเดอร์นั้น ฉันสาบานว่าฉันไม่รู้ว่าใครเป็นคนทำ (หนึ่งในข้อบกพร่อง / คุณสมบัติที่ฉันโปรดปราน)
Sean Patrick Floyd

6

การจับข้อยกเว้นทั่วไป:

try {

 ...

} catch {
}

หรือ

try {

 ...

} catch (Exception ex) {
}

ภูมิภาคมากเกินไป

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


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

+1 สำหรับตัวอย่าง 'จับแล้วทิ้งยกเว้น' หากคุณไม่ได้ทำสิ่งใดโดยมีข้อยกเว้น อย่างน้อยที่สุดให้เข้าสู่ระบบ อย่างน้อยที่สุดก็ใส่ความคิดเห็นอธิบายว่าทำไมมันก็โอเคที่จะจับข้อยกเว้นทั้งหมดและไปที่จุดนั้นในรหัส
EZ Hart

5

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

ตัวอย่างที่เด่นชัดขึ้นมาในชั้นเรียน VB ที่ฉันเห็นครั้งหนึ่งเคยมีชื่อว่าDataและมีความยาวมากกว่า 30,000 บรรทัด ... ในไฟล์แรก มันเป็นชั้นบางส่วนแบ่งออกเป็นอย่างน้อยครึ่งโหลไฟล์อื่น ๆ ส่วนใหญ่ของวิธีการที่ถูกห่อรอบ procs FindXByYWithZ()เก็บที่มีชื่อเหมือน

แม้จะมีตัวอย่างที่น่าทึ่งน้อยกว่าฉันแน่ใจว่าเราทุกคนแค่ 'ทิ้ง' ตรรกะในชั้นเรียนที่ไม่ดีให้มันเป็นชื่อสามัญทั้งหมดและเสียใจในภายหลัง


5

ฟังก์ชั่นที่ปรับใช้การทำงานพื้นฐานของภาษาอีกครั้ง ตัวอย่างเช่นหากคุณเคยเห็นเมธอด "getStringLength ()" ใน JavaScript แทนที่จะเรียกใช้คุณสมบัติ ".length" ของสตริงคุณจะรู้ว่าคุณกำลังมีปัญหา


5
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...
#define ...

แน่นอนโดยไม่ต้องใด ๆ ของเอกสารและบางครั้งซ้อนกัน#defines


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