ความยาวฟังก์ชั่นส่งผลกระทบต่อผลผลิตของโปรแกรมเมอร์หรือไม่? ถ้าเป็นเช่นนั้นจำนวนบรรทัดที่ดีที่สุดที่ควรหลีกเลี่ยงคือการสูญเสียผลผลิต
เนื่องจากเป็นหัวข้อที่มีความคิดเห็นสูงโปรดสำรองข้อมูลการอ้างสิทธิ์ด้วยข้อมูลบางส่วน
ความยาวฟังก์ชั่นส่งผลกระทบต่อผลผลิตของโปรแกรมเมอร์หรือไม่? ถ้าเป็นเช่นนั้นจำนวนบรรทัดที่ดีที่สุดที่ควรหลีกเลี่ยงคือการสูญเสียผลผลิต
เนื่องจากเป็นหัวข้อที่มีความคิดเห็นสูงโปรดสำรองข้อมูลการอ้างสิทธิ์ด้วยข้อมูลบางส่วน
คำตอบ:
ตั้งแต่ฉันลงมือบนแร็คเก็ตบ้านี้ในปี 1970 ฉันได้เห็นโมดูลหนึ่งเดียวที่จำเป็นต้องมีมากกว่าหนึ่งหน้าพิมพ์ (ประมาณ 60 บรรทัด) ฉันได้เห็นโมดูลมากมายที่ยาวกว่านี้
สำหรับเรื่องนั้นฉันได้เขียนโมดูลที่ยาวกว่า แต่โดยปกติแล้วพวกเขามักเป็นเครื่องจักรขนาดใหญ่ที่มี จำกัด ซึ่งเขียนเป็นคำสั่งสวิตช์ขนาดใหญ่
ส่วนหนึ่งของปัญหาดูเหมือนว่าผู้เขียนโปรแกรมสมัยนี้ไม่ได้รับการสอนให้ทำสิ่งต่างๆ
มาตรฐานการเข้ารหัสที่เพิ่มความสิ้นเปลืองของพื้นที่แนวตั้งให้มากที่สุดก็เป็นส่วนหนึ่งของปัญหาเช่นกัน (ฉันยังไม่ได้พบกับผู้จัดการซอฟต์แวร์ที่ได้อ่าน" จิตวิทยาการเขียนโปรแกรมคอมพิวเตอร์ " ของGerald Weinberg Weinberg ชี้ให้เห็นว่าการศึกษาหลายครั้งได้แสดงให้เห็นว่าการเข้าใจโปรแกรมเมอร์นั้น จำกัด อยู่ที่สิ่งที่โปรแกรมเมอร์สามารถเห็นได้ในทันที โปรแกรมเมอร์ต้องเลื่อนหรือเปิดหน้าความเข้าใจของพวกเขาลดลงอย่างมีนัยสำคัญพวกเขาต้องจำและสรุป)
ฉันยังคงเชื่อมั่นว่าผลผลิตโปรแกรมเมอร์ที่ได้รับการบันทึกไว้อย่างดีจำนวนมากที่ได้รับจากFORTHนั้นเกิดจากระบบ "บล็อก" ของ FORTH สำหรับซอร์สโค้ด: โมดูลนั้น จำกัด อย่างหนักถึง 16 บรรทัดสูงสุด 64 บรรทัด คุณสามารถแยกปัจจัยอนันต์ แต่คุณไม่สามารถอยู่ภายใต้สถานการณ์ใด ๆ ก็ตามไม่ว่าจะเขียนรูทีน 17 บรรทัด
ขึ้นอยู่กับภาษาที่คุณใช้ แต่โดยทั่วไป (และเพื่อรสนิยมส่วนตัวของฉัน):
ถ้ามันมากกว่านั้นมันเป็นสิ่งที่ฉันต้องกลับมาในภายหลังและทำใหม่
แต่ในความเป็นจริงขนาดใดก็ได้ที่คุณต้องการเมื่อคุณต้องการส่งมอบบางสิ่งบางอย่างและมันสมเหตุสมผลกว่าในขณะนี้ที่จะคายมันออกมาแบบนั้นทำให้บางครั้งง่ายขึ้นสำหรับคนที่จะตรวจสอบก่อนส่งสินค้า (แต่ยังคงกลับไปใช้ในภายหลัง)
(เมื่อเร็ว ๆ นี้ทีมของฉันรันโปรแกรมบนโค้ดเบสของเรา: เราพบคลาสที่มี 197 วิธีและอีก 3 วิธีเท่านั้น แต่หนึ่งในนั้นคือ 600 ไลน์เกมน่ารัก: อะไรเลวร้ายกว่าของ 2 สิ่งเลวร้าย)
ตอนนี้สำหรับคำตอบที่เซนเพิ่มเติม ... โดยทั่วไปจะถือว่าเป็นวิธีปฏิบัติที่ดี (TM) ในการอ้างอิงชายผู้ยิ่งใหญ่หนึ่งหรือสองคนดังนั้นต่อไปนี้:
ทุกอย่างควรทำง่ายที่สุด แต่ไม่ง่ายกว่า - A. Einstein
ในที่สุดความสมบูรณ์แบบก็จะไม่เกิดขึ้นเมื่อไม่มีสิ่งใดที่จะเพิ่มอีกต่อไป แต่เมื่อไม่มีสิ่งใดที่จะเอาไปอีก - A. de Saint Exupéry
ภาคผนวกของสิ่งนี้หน้าที่ของคุณควรมีชื่อที่ชัดเจนที่อธิบายถึงเจตนาของพวกเขา เกี่ยวกับความคิดเห็นฉันมักจะไม่แสดงความคิดเห็นในฟังก์ชั่น:
บล็อกข้อคิดเห็นที่ด้านบนของแต่ละฟังก์ชัน (ที่ต้องมีคำอธิบาย) ก็เพียงพอแล้ว หากฟังก์ชั่นของคุณมีขนาดเล็กและชื่อฟังก์ชั่นนั้นมีความชัดเจนเพียงพอคุณควรจะต้องพูดในสิ่งที่คุณต้องการเพื่อให้บรรลุและเพราะเหตุใด ฉันใช้ความคิดเห็นแบบอินไลน์เฉพาะสำหรับฟิลด์ในบางภาษาหรือในการเริ่มต้นบล็อกสำหรับฟังก์ชั่นที่ละเมิดกฎบรรทัด 25-35 หากเจตนาไม่ชัดเจน ฉันใช้ความคิดเห็นแบบบล็อกในโค้ดเมื่อมีสถานการณ์พิเศษเกิดขึ้น (บล็อกแบบจับที่คุณไม่ต้องการหรือต้องการทำอะไรควรมีความคิดเห็นที่บอกว่าทำไมยกตัวอย่างเช่น)
สำหรับข้อมูลเพิ่มเติมโปรดอ่านคำตอบของฉันเกี่ยวกับรูปแบบและคำแนะนำของรหัสความคิดเห็น
tt
เพื่อสร้างสิ่งเหล่านี้ แต่บางครั้งคุณก็ติดอยู่กับฟังก์ชั่นลายาว (หรือฟังก์ชั่นที่ใช้เวลานาน) ซึ่งไม่ได้สนใจอะไรเลย
Map(x => x.Property1); Map(x => x.Property2); Map(x => x.Property3);
มันชัดเจนว่ามันค่อนข้างเหมือนกันทั้งหมด (โปรดทราบว่านี่เป็นเพียงตัวอย่างฟังก์ชันประเภทนี้จะปรากฏขึ้นเป็นครั้งคราว)
ในความคิดของฉันทุกฟังก์ชั่นควรมีขนาดเล็กที่สุด แต่ละฟังก์ชั่นควรทำเพียงสิ่งเดียวและทำได้ดี ไม่ได้ตอบคำถามที่มีความยาวสูงสุดจริง ๆ แต่มันเป็นความรู้สึกของฉันต่อความยาวของฟังก์ชั่น
หากต้องการใช้คำพูดของลุงบ๊อบ"ดึงข้อมูลจนกว่าคุณจะไม่สามารถแยกข้อมูลได้อีกแล้วแยกข้อมูลจนกว่าคุณจะลดลง"
สิ่งที่ควรเป็นความสูงสูงสุดของอาคาร ขึ้นอยู่กับว่า build อยู่ที่ไหนหรือความสูงที่คุณต้องการให้เป็น
คุณอาจได้รับคำตอบที่แตกต่างจากคนอื่นที่มาจากเมืองต่าง ๆ
ฟังก์ชันสคริปต์และตัวจัดการขัดจังหวะเคอร์เนลบางตัวมีความยาวมาก
วิธีที่เหมาะกับฉันคือฉันขอให้ส่วนหนึ่งของฟังก์ชั่นอีกต่อไปตั้งชื่อที่เหมาะสมได้ไหม ฉันคิดว่าความยาวของวิธีการนั้นไม่สำคัญเท่ากับการตั้งชื่อที่ดี วิธีการควรทำในสิ่งที่ชื่อพูดไม่มากไปกว่านี้ และคุณควรจะสามารถให้ชื่อที่ดี หากคุณไม่สามารถตั้งชื่อวิธีการของคุณได้ดีรหัสนั้นอาจไม่ดีพอ
ตราบใดที่มันต้องทำสิ่งที่มันต้องทำ แต่ไม่นาน
ฉันคิดว่ามีการแลกเปลี่ยน หากคุณมีวิธีการสั้น ๆ มากมายมักจะยากที่จะทำการดีบั๊กมากกว่าวิธียาว ๆ หากคุณต้องข้ามโปรแกรมแก้ไข 20 หรือ 30 ครั้งเพื่อติดตามการโทรด้วยวิธีเดียวมันจะยากที่จะเก็บมันไว้ในหัวของคุณ ในขณะเดียวกันถ้ามีวิธีการเขียนที่ชัดเจนอย่างหนึ่งแม้ว่ามันจะเป็น 100 บรรทัดมันก็มักจะง่ายต่อการรักษาไว้ในหัวของคุณ
คำถามจริงคือเหตุผลที่รายการควรอยู่ในวิธีการที่แตกต่างกันและคำตอบตามที่ได้รับข้างต้นคือการใช้รหัสซ้ำ หากคุณไม่ได้ใช้รหัสอีกครั้ง (หรือไม่รู้) คุณอาจต้องทิ้งมันไว้ในยักษ์ตัวเดียวที่ง่ายต่อการปฏิบัติตามวิธีการและจากนั้นเมื่อคุณจำเป็นต้องใช้มันอีกครั้งให้แยกส่วนที่ต้องการอีกครั้ง ใช้เป็นวิธีการขนาดเล็ก
ในความเป็นจริงส่วนหนึ่งของการออกแบบวิธีการที่ดีคือการทำให้วิธีการทำงานร่วมกันอย่างเหนียวแน่น ความยาวของวิธีการไม่สำคัญ หากฟังก์ชั่นทำสิ่งหนึ่งที่กำหนดไว้อย่างดีและมี 1,000 บรรทัดมากกว่านั้นเป็นวิธีที่ดี หากฟังก์ชั่นทำสิ่งที่ 3 หรือ 4 และมีเพียง 15 บรรทัดก็เป็นวิธีที่ไม่ดี ...
ฉันพบว่าการติดตามสิ่งที่ฉันกำลังทำง่ายขึ้นถ้าฉันสามารถดูฟังก์ชั่นทั้งหมดได้ในครั้งเดียว ดังนั้นนี่คือวิธีที่ฉันชอบเขียนฟังก์ชั่น:
ฉันไม่ค่อยเขียนฟังก์ชันนานกว่านั้น ส่วนใหญ่เป็นคำสั่งสวิตช์ C / C ++ ขนาดยักษ์
สำหรับฉันฟังก์ชั่นคือความยาวใด ๆ ที่มันจำเป็นต้องมี เวลาส่วนใหญ่ที่ฉันแบ่งไว้คือเมื่อฉันจะใช้รหัสซ้ำ
โดยพื้นฐานแล้วฉันจะยึดติดกับ 'ความต่อเนื่องสูงการมีเพศสัมพันธ์ต่ำ' และไม่มีข้อ จำกัด เรื่องความยาว
คำถามควรมีฟังก์ชั่นที่ควรทำ และโดยปกติจะหายากที่คุณต้องการ 100 บรรทัดในการทำสิ่ง "หนึ่ง" อีกครั้งที่ขึ้นอยู่กับระดับที่คุณกำลังดูรหัส: การแฮรหัสผ่านเป็นสิ่งหนึ่งหรือไม่ หรือ hashing และบันทึกรหัสผ่านสิ่งหนึ่ง
ฉันจะบอกว่าเริ่มต้นด้วยการบันทึกรหัสผ่านเป็นฟังก์ชั่นเดียว เมื่อคุณรู้สึกว่าการแฮ็กนั้นแตกต่างกันและคุณปรับโครงสร้างโค้ดอีกครั้ง ฉันไม่มีโปรแกรมเมอร์ผู้เชี่ยวชาญ แต่อย่างใด IMHO ความคิดทั้งหมดของฟังก์ชั่นเริ่มต้นเพียงเล็กน้อยก็คือยิ่งฟังก์ชั่นของคุณมีขนาดใหญ่ขึ้นโอกาสที่จะใช้รหัสซ้ำสูงขึ้นโดยที่ไม่ต้องทำการเปลี่ยนแปลงแบบเดียวกันในที่เดียว ฯลฯ
ฉันได้เห็นSQL ที่ จัดเก็บโพรซีเดอร์ที่รันมากกว่า 1,000 บรรทัด จำนวนบรรทัดของโพรซีเดอร์ที่เก็บยังน้อยกว่า 50 หรือไม่? ฉันไม่รู้ แต่มันทำให้การอ่านรหัสเป็นไปได้ คุณไม่เพียง แต่ต้องเลื่อนขึ้นลงเรื่อย ๆ คุณต้องให้ชื่อโค้ดสองสามบรรทัดเช่น "this validation1", "การอัปเดตนี้ในฐานข้อมูล" ฯลฯ - งานที่โปรแกรมเมอร์ควรทำ
จากความซับซ้อนของวัฏจักร (Wikipedia):
ความสลับซับซ้อนของส่วนของซอร์สโค้ดคือการนับจำนวนของเส้นทางที่เป็นอิสระเชิงเส้นผ่านซอร์สโค้ด
ฉันแนะนำให้คุณเก็บหมายเลขนั้นไว้ต่ำกว่า 10 ในวิธีเดียว หากถึง 10 แสดงว่าถึงเวลาแล้วที่จะต้องคำนึงถึงปัจจัยใหม่
มีเครื่องมือที่สามารถประเมินโค้ดของคุณและให้หมายเลขความซับซ้อนของวงจร
คุณควรพยายามรวมเครื่องมือเหล่านี้เข้ากับขั้นตอนการสร้างของคุณ
อย่าไล่ตามขนาดวิธีการ แต่พยายามดูความซับซ้อนและความรับผิดชอบของมัน ถ้ามันมีความรับผิดชอบมากกว่าหนึ่งอย่างมันอาจเป็นความคิดที่ดีที่จะพิจารณาปัจจัยใหม่ หากความซับซ้อนของวงจรเพิ่มขึ้นอาจถึงเวลาที่ต้องพิจารณาปัจจัยใหม่
ฉันค่อนข้างแน่ใจว่ามีเครื่องมืออื่น ๆ ที่ให้ข้อเสนอแนะที่คล้ายกัน แต่ฉันยังไม่มีโอกาสได้ตรวจสอบเรื่องนี้
โดยปกติแล้วฉันพยายามที่จะรักษาวิธีการ / ฟังก์ชั่นของฉันให้พอดีกับหน้าจอของจอภาพ 1680x1050 ถ้ามันไม่พอดีให้ใช้วิธีการ / ฟังก์ชั่นตัวช่วยเพื่อแยกงาน
ช่วยให้อ่านได้ทั้งบนหน้าจอและกระดาษ
สั้นพอที่จะปรับให้เหมาะสมอย่างถูกต้อง
วิธีการควรสั้นจนทำสิ่งหนึ่งอย่างแน่นอน เหตุผลนี้ง่ายมาก: เพื่อให้รหัสของคุณสามารถปรับให้เหมาะสม
ในภาษา JIT-ted เช่น Java หรือ C # เป็นสิ่งสำคัญที่วิธีการของคุณจะง่ายเพื่อให้ผู้แปล JIT สามารถผลิตรหัสได้อย่างรวดเร็ว วิธีการที่ยาวและซับซ้อนกว่านั้นต้องใช้เวลามากกว่า JIT นอกจากนี้คอมไพเลอร์ของ JIT จะนำเสนอการเพิ่มประสิทธิภาพเพียงเล็กน้อยเท่านั้นและวิธีการที่ง่ายที่สุดจะได้รับประโยชน์จากสิ่งนี้ ความจริงเรื่องนี้ถูกเรียกว่าแม้จะออกมาในบิลวากเนอร์ที่มีประสิทธิภาพ C #
ในภาษาระดับต่ำกว่าเช่น C หรือ C ++ การมีวิธีการสั้น ๆ (อาจจะเป็นโหลหรือมากกว่านั้น) ก็มีความสำคัญเช่นกันเพราะวิธีการที่คุณลดความต้องการในการจัดเก็บตัวแปรโลคัลใน RAM แทนการลงทะเบียน (Aka 'Register Spilling') โปรดทราบว่าในกรณีที่ไม่มีการจัดการค่าใช้จ่ายสัมพัทธ์ของการเรียกใช้ฟังก์ชันแต่ละครั้งอาจสูงมาก
และแม้แต่ในภาษาแบบไดนามิกเช่น Ruby หรือ Python การมีวิธีสั้น ๆ ก็ช่วยในการปรับแต่งคอมไพเลอร์ด้วยเช่นกัน ในภาษาไดนามิกคุณสมบัติยิ่ง 'ไดนามิก' ยิ่งยากที่จะปรับให้เหมาะสม ตัวอย่างเช่นวิธีการแบบยาวซึ่งใช้ X และสามารถคืนค่า Int, Float หรือ String จะทำงานช้ากว่าวิธีที่แยกกันสามวิธีซึ่งแต่ละวิธีจะส่งคืนชนิดเดียวเท่านั้น นี่เป็นเพราะหากคอมไพเลอร์รู้ว่าฟังก์ชั่นประเภทใดที่จะกลับมาก็สามารถเพิ่มประสิทธิภาพเว็บไซต์โทรฟังก์ชั่นเช่นกัน (เช่นไม่ใช่การตรวจสอบการแปลงประเภท)
ฉันไม่ได้ จำกัด จำนวนบรรทัดไว้ที่อะไรเลยเพราะบางฟังก์ชั่นใช้อัลกอริธึมที่ซับซ้อนโดยเนื้อแท้และความพยายามใด ๆ ที่ทำให้พวกมันสั้นลงจะทำให้ปฏิสัมพันธ์ระหว่างฟังก์ชั่นใหม่และสั้นลงดังนั้นซับซ้อน ฉันยังไม่เชื่อว่าความคิดที่ว่าฟังก์ชั่นควรทำเพียง "สิ่งเดียว" เป็นแนวทางที่ดีเนื่องจาก "สิ่งหนึ่งสิ่ง" ในระดับสูงของสิ่งที่เป็นนามธรรมอาจเป็น "หลายสิ่ง" ในระดับที่ต่ำกว่า
สำหรับฉันแล้วฟังก์ชั่นนั้นยาวเกินไปถ้าความยาวของมันทำให้เกิดการละเมิด DRY ที่ลึกซึ้งในตอนนี้และการแยกส่วนของฟังก์ชั่นออกเป็นฟังก์ชั่นใหม่หรือคลาสสามารถแก้ปัญหานี้ได้ ฟังก์ชั่นอาจยาวเกินไปหากไม่ใช่ในกรณีนี้ แต่สามารถแยกฟังก์ชันหรือคลาสได้อย่างง่ายดายซึ่งจะทำให้โค้ดเป็นแบบแยกส่วนมากขึ้นในลักษณะที่น่าจะเป็นประโยชน์ในการเผชิญกับการเปลี่ยนแปลงที่คาดการณ์ไว้
มันขึ้นอยู่กับว่ามีอะไรในรหัส
ฉันได้เห็นรูทีนพันบรรทัดที่ฉันไม่มีปัญหา มันเป็นคำสั่งสวิตช์ขนาดใหญ่ไม่มีตัวเลือกเกินกว่าหนึ่งโหลบรรทัดและโครงสร้างการควบคุมเดียวในตัวเลือกใด ๆ คือลูปเดียว วันนี้มันจะถูกเขียนด้วยวัตถุ แต่นั่นไม่ใช่ตัวเลือกกลับมาแล้ว
ฉันยังดูที่ 120 บรรทัดในสวิตช์ด้านหน้าฉัน ไม่มีกรณีเกิน 3 บรรทัด - การป้องกันการมอบหมายและการหยุดพัก มันกำลังแจงไฟล์ข้อความวัตถุไม่น่าจะเป็นไปได้ ทางเลือกใด ๆ ก็ยากที่จะอ่าน
คอมไพเลอร์ส่วนใหญ่ไม่คำนึงถึงความยาวของฟังก์ชัน ฟังก์ชั่นควรใช้งานได้ แต่มีทั้งง่ายต่อการเข้าใจเปลี่ยนแปลงและนำกลับมาใช้กับมนุษย์ เลือกความยาวที่เหมาะกับคุณที่สุด
กฎทั่วไปของฉันคือฟังก์ชั่นควรจะพอดีกับหน้าจอ มีเพียงสามกรณีที่ฉันพบว่ามีแนวโน้มที่จะละเมิดสิ่งนี้:
1) ฟังก์ชั่นการจัดส่ง ในสมัยก่อนสิ่งเหล่านี้เป็นเรื่องธรรมดา แต่ส่วนใหญ่จะถูกแทนที่ด้วยการสืบทอดวัตถุสมัยนี้ วัตถุจะทำงานภายในโปรแกรมของคุณเท่านั้นดังนั้นคุณจะยังคงเห็นฟังก์ชั่นการจัดส่งเป็นครั้งคราวเมื่อจัดการกับข้อมูลที่มาจากที่อื่น
2) ฟังก์ชั่นที่ทำทั้งขั้นตอนเพื่อบรรลุเป้าหมายและขั้นตอนที่ขาดการแบ่งที่ดี คุณจบลงด้วยฟังก์ชั่นที่เรียกรายการฟังก์ชันอื่น ๆ ตามลำดับ
3) เหมือน # 2 แต่ในกรณีที่แต่ละขั้นตอนมีขนาดเล็กมากพวกมันจะถูก inline แทนที่จะเรียกแยกต่างหาก
บางทีความยาวของฟังก์ชั่นอาจไม่ได้ดีนัก เราพยายามใช้ความซับซ้อนของวงจรในวิธีการเช่นกันและหนึ่งในกฎการตรวจสอบแหล่งที่มาในอนาคตควบคุมว่าความซับซ้อนของวงจรในชั้นเรียนและวิธีการต้องต่ำกว่า X
สำหรับวิธีการ X ตั้งค่าเป็น 30 และนั่นค่อนข้างแน่น