การเรียนรู้โดยไม่ต้องคิดคือการสูญเสียแรงงาน การคิดโดยไม่เรียนรู้ก็เป็นอันตราย
นินจาโปรแกรมเมอร์ในอดีตใช้เทคนิคเหล่านี้เพื่อฝึกฝนจิตใจของผู้ดูแลโค้ด
ผู้เชี่ยวชาญด้านการทบทวนโค้ดจะมองหาพวกเขาในงานทดสอบ
นักพัฒนามือใหม่บางครั้งใช้มันได้ดีกว่านินจาโปรแกรมเมอร์ด้วยซ้ำ
อ่านอย่างละเอียดและค้นหาว่าคุณเป็นใคร ไม่ว่าจะเป็นนินจา มือใหม่ หรืออาจจะเป็นผู้ตรวจสอบโค้ด?
ตรวจพบการประชด
หลายคนพยายามติดตามเส้นทางของนินจา ไม่กี่คนที่ประสบความสำเร็จ
จัดทำโค้ดให้สั้นที่สุด แสดงว่าคุณฉลาดแค่ไหน
ให้คุณสมบัติภาษาที่ละเอียดอ่อนนำทางคุณ
ตัวอย่างเช่น ลองดูตัวดำเนินการที่ประกอบไปด้วย '?'
-
// นำมาจากไลบรารีจาวาสคริปต์ที่รู้จักกันดี ฉัน = ฉัน ? ฉัน < 0 ? Math.max(0, เลน + i) : i : 0;
เจ๋งใช่มั้ย? ถ้าคุณเขียนแบบนั้น นักพัฒนาที่เจอบรรทัดนี้และพยายามทำความเข้าใจว่าค่า i
คืออะไร จะต้องมีความสุขอย่างแน่นอน แล้วมาหาคุณเพื่อค้นหาคำตอบ
บอกพวกเขาว่าสั้นกว่าจะดีกว่าเสมอ เริ่มต้นพวกเขาเข้าสู่เส้นทางของนินจา
Dao ซ่อนตัวอยู่ในความไร้คำพูด มีเพียงเต๋าเท่านั้นที่เริ่มต้นได้ดีและสมบูรณ์ดี
อีกวิธีหนึ่งในการเขียนโค้ดให้สั้นลงคือการใช้ชื่อตัวแปรที่มีตัวอักษรเดี่ยวทุกที่ เช่น a
, b
หรือ c
ตัวแปรสั้นๆ หายไปในโค้ดเหมือนกับนินจาตัวจริงในป่า จะไม่มีใครสามารถค้นพบได้โดยใช้ "การค้นหา" ของโปรแกรมแก้ไข และแม้ว่าจะมีใครก็ตาม พวกเขาก็จะไม่สามารถ "ถอดรหัส" ว่าชื่อ a
หรือ b
หมายถึงอะไรได้
…แต่ก็มีข้อยกเว้นอยู่ นินจาตัวจริงจะไม่มีวันใช้ i
เป็นตัวนับในลูป "for"
ที่ไหนก็ได้ แต่ไม่ใช่ที่นี่ มองไปรอบ ๆ มีตัวอักษรแปลก ๆ อีกมากมาย ตัวอย่างเช่น x
หรือ y
ตัวแปรแปลกใหม่เป็นตัวนับลูปจะเจ๋งเป็นพิเศษหากตัวลูปใช้เวลา 1-2 หน้า (ทำให้ยาวขึ้นถ้าทำได้) ถ้ามีคนมองลึกเข้าไปในลูป พวกเขาจะไม่สามารถรู้ได้อย่างรวดเร็วว่าตัวแปรชื่อ x
เป็นตัวนับลูป
หากทีมออกกฎห้ามใช้ตัวอักษรตัวเดียวและชื่อที่คลุมเครือ ให้ย่อให้สั้นลงและเขียนตัวย่อ
แบบนี้:
list
→ lst
.
userAgent
→ ua
browser
→ brsr
.
… ฯลฯ
ผู้ที่มีสัญชาตญาณที่ดีอย่างแท้จริงเท่านั้นจึงจะสามารถเข้าใจชื่อดังกล่าวได้ พยายามย่อทุกอย่างให้สั้นลง มีเพียงคนที่มีค่าควรเท่านั้นที่สามารถสนับสนุนการพัฒนาโค้ดของคุณได้
จัตุรัสใหญ่ไม่มีมุม
เรือใหญ่ลำสุดท้ายเสร็จสมบูรณ์แล้ว
โน้ตที่ยิ่งใหญ่คือเสียงที่หายาก
ภาพลักษณ์อันยิ่งใหญ่ไม่มีรูปแบบ
ในขณะที่เลือกชื่อพยายามใช้คำที่เป็นนามธรรมที่สุด เช่น obj
, data
, value
, item
, elem
และอื่นๆ
ชื่อที่เหมาะสมที่สุดสำหรับตัวแปรคือ data
ใช้ทุกที่ที่คุณสามารถทำได้ แท้จริงแล้วทุกตัวแปรเก็บ ข้อมูล ใช่ไหม
…แต่จะทำอย่างไรหาก data
ถูกนำไปใช้แล้ว? ลอง value
มันก็เป็นสากลเช่นกัน ท้ายที่สุดแล้ว ตัวแปรจะได้รับ ค่า ในที่สุด
ตั้งชื่อตัวแปรตามประเภทของมัน: str
, num
…
ให้พวกเขาลอง ผู้ประทับจิตรุ่นเยาว์อาจสงสัยว่า ชื่อดังกล่าวมีประโยชน์สำหรับนินจาจริงหรือ? แท้จริงแล้วพวกเขาเป็น!
แน่นอนว่าชื่อตัวแปรยังคงมีความหมายบางอย่าง มันบอกว่ามีอะไรอยู่ในตัวแปร: สตริง, ตัวเลข หรืออย่างอื่น แต่เมื่อบุคคลภายนอกพยายามทำความเข้าใจโค้ด พวกเขาจะแปลกใจเมื่อเห็นว่าจริงๆ แล้วไม่มีข้อมูลเลย! และท้ายที่สุดจะล้มเหลวในการแก้ไขโค้ดที่คุณคิดดีแล้ว
ประเภทของค่านั้นง่ายต่อการค้นหาโดยการดีบัก แต่ความหมายของตัวแปรคืออะไร? เก็บสาย/หมายเลขใดไว้?
ไม่มีทางที่จะเข้าใจได้หากไม่มีการทำสมาธิที่ดี!
…แต่จะเกิดอะไรขึ้นถ้าไม่มีชื่อดังกล่าวอีกต่อไป? เพียงเพิ่มตัวเลข: data1, item2, elem5
…
เฉพาะโปรแกรมเมอร์ที่เอาใจใส่อย่างแท้จริงเท่านั้นจึงจะสามารถเข้าใจโค้ดของคุณได้ แต่จะตรวจสอบได้อย่างไร?
วิธีหนึ่ง – ใช้ชื่อตัวแปรที่คล้ายกัน เช่น date
และ data
ผสมให้เข้ากัน
การอ่านโค้ดดังกล่าวอย่างรวดเร็วจะเป็นไปไม่ได้ และเวลาที่พิมพ์ผิด… อืม… เราติดอยู่นานมาก ได้เวลาดื่มชาแล้ว
เต๋าที่บอกได้ไม่ใช่เต๋านิรันดร์ ชื่อที่สามารถตั้งชื่อได้ไม่ใช่ชื่อนิรันดร์
การใช้ชื่อ ที่คล้ายกัน สำหรับสิ่ง เดียวกัน ทำให้ชีวิตน่าสนใจยิ่งขึ้นและแสดงความคิดสร้างสรรค์ของคุณต่อสาธารณะ
ตัวอย่างเช่น พิจารณาคำนำหน้าฟังก์ชัน หากฟังก์ชันแสดงข้อความบนหน้าจอ ให้เริ่มต้นด้วย display…
เช่น displayMessage
จากนั้นหากฟังก์ชันอื่นแสดงอย่างอื่นบนหน้าจอ เช่น ชื่อผู้ใช้ ให้เริ่มต้นด้วย show…
(เช่น showName
)
บอกเป็นนัยว่ามีความแตกต่างเล็กน้อยระหว่างฟังก์ชันดังกล่าว ในขณะที่ไม่มีเลย
ทำข้อตกลงกับเพื่อนนินจาในทีม: หาก John เริ่ม "แสดง" ฟังก์ชั่นด้วย display...
ในโค้ดของเขา Peter ก็สามารถใช้ render..
และ Ann – paint...
. สังเกตว่าโค้ดมีความน่าสนใจและหลากหลายมากขึ้นเพียงใด
…และตอนนี้แฮตทริก!
สำหรับสองฟังก์ชันที่มีความแตกต่างที่สำคัญ – ใช้คำนำหน้าเดียวกัน!
ตัวอย่างเช่น ฟังก์ชัน printPage(page)
จะใช้เครื่องพิมพ์ และฟังก์ชัน printText(text)
จะใส่ข้อความบนหน้าจอ ให้ผู้อ่านที่ไม่คุ้นเคยคิดให้ดีเกี่ยวกับฟังก์ชันที่มีชื่อคล้ายกัน printMessage
: “มันใส่ข้อความไว้ที่ไหน? ไปยังเครื่องพิมพ์หรือบนหน้าจอ?” เพื่อให้มันโดดเด่นจริงๆ printMessage(message)
ควรส่งออกมันในหน้าต่างใหม่!
เมื่อแบ่งส่วนทั้งหมดแล้ว
ต้องการชื่อ
มีชื่อเพียงพอแล้ว
เราต้องรู้ว่าเมื่อใดควรหยุด
เพิ่มตัวแปรใหม่เมื่อจำเป็นจริงๆ เท่านั้น
ให้ใช้ชื่อที่มีอยู่ซ้ำแทน เพียงเขียนค่าใหม่ลงไป
ในฟังก์ชันพยายามใช้เฉพาะตัวแปรที่ส่งผ่านเป็นพารามิเตอร์
นั่นจะทำให้เป็นเรื่องยากมากที่จะระบุสิ่งที่อยู่ในตัวแปร ตอนนี้ และยังมาจากที่ใด จุดประสงค์คือเพื่อพัฒนาสัญชาตญาณและความทรงจำของบุคคลที่อ่านโค้ด บุคคลที่มีสัญชาตญาณอ่อนแอจะต้องวิเคราะห์โค้ดทีละบรรทัดและติดตามการเปลี่ยนแปลงผ่านทุกสาขาของโค้ด
รูปแบบขั้นสูงของแนวทางคือการแทนที่ค่าอย่างซ่อนเร้น (!) ด้วยสิ่งที่เหมือนกันตรงกลางของลูปหรือฟังก์ชัน
ตัวอย่างเช่น:
ฟังก์ชั่น ninjaFunction (องค์ประกอบ) { // โค้ด 20 บรรทัดทำงานกับองค์ประกอบ องค์ประกอบ = โคลน (องค์ประกอบ); // อีก 20 บรรทัด ตอนนี้ทำงานกับโคลนขององค์ประกอบได้แล้ว! -
เพื่อนโปรแกรมเมอร์ที่ต้องการทำงานกับ elem
ในช่วงครึ่งหลังของฟังก์ชันจะต้องประหลาดใจ... เฉพาะในระหว่างการดีบัก หลังจากตรวจสอบโค้ดแล้ว พวกเขาจะพบว่าพวกเขากำลังทำงานกับโคลน!
เห็นในโค้ดเป็นประจำ มีประสิทธิภาพถึงตายแม้กระทั่งกับนินจาผู้มีประสบการณ์
ใส่ขีดล่าง _
และ __
ก่อนชื่อตัวแปร ชอบ _name
หรือ __value
คงจะดีไม่น้อยหากคุณรู้ความหมายของมัน หรือดีกว่านั้น เพิ่มไว้เพื่อความสนุกสนานเท่านั้น โดยไม่มีความหมายใดๆ เป็นพิเศษเลย หรือความหมายต่างกันไปในที่ต่างๆ
คุณฆ่ากระต่ายสองตัวด้วยนัดเดียว อย่างแรก โค้ดจะยาวขึ้นและอ่านน้อยลง และอย่างที่สอง นักพัฒนาคนอื่นๆ อาจใช้เวลานานในการพยายามหาว่าขีดล่างหมายถึงอะไร
นินจาผู้ชาญฉลาดใส่ขีดล่างไว้ที่จุดหนึ่งของโค้ดและหลบไปที่จุดอื่น นั่นทำให้โค้ดเปราะบางยิ่งขึ้นและเพิ่มความน่าจะเป็นของข้อผิดพลาดในอนาคต
ให้ทุกคนเห็นว่าตัวตนของคุณงดงามแค่ไหน! ชื่ออย่าง superElement
, megaFrame
และ niceItem
จะทำให้ผู้อ่านกระจ่างขึ้นอย่างแน่นอน
อันที่จริง มีบางอย่างเขียนจากมือข้างหนึ่ง: super..
, mega..
, nice..
แต่ในอีกด้านหนึ่ง – ที่ไม่ได้นำรายละเอียดมา ผู้อ่านอาจตัดสินใจมองหาความหมายที่ซ่อนอยู่และนั่งสมาธิสักหนึ่งหรือสองชั่วโมงจากเวลาทำงานที่ได้รับค่าจ้าง
เมื่ออยู่ในแสงสว่างมองไม่เห็นสิ่งใดในความมืด
เมื่ออยู่ในความมืดสามารถมองเห็นทุกสิ่งในแสงสว่างได้
ใช้ชื่อเดียวกันสำหรับตัวแปรภายในและภายนอกฟังก์ชัน เรียบง่าย ไม่มีความพยายามที่จะคิดค้นชื่อใหม่
ให้ผู้ใช้ = AuthenticateUser(); ฟังก์ชั่นเรนเดอร์ () { ให้ผู้ใช้ = anotherValue(); - ...หลายบรรทัด... - ... // <-- โปรแกรมเมอร์ต้องการทำงานกับผู้ใช้ที่นี่ และ... - -
โปรแกรมเมอร์ที่กระโดดเข้าไปใน render
อาจจะไม่สังเกตเห็นว่ามี user
ในเครื่องคอยดูผู้ใช้ภายนอก
จากนั้นพวกเขาจะพยายามทำงานกับ user
โดยสมมติว่าเป็นตัวแปรภายนอก ผลลัพธ์ของ authenticateUser()
… กับดักถูกเด้งแล้ว! สวัสดี ดีบักเกอร์...
มีฟังก์ชั่นที่ดูเหมือนไม่มีการเปลี่ยนแปลงอะไรเลย เช่นเดียวกับ isReady()
, checkPermission()
, findTags()
… พวกเขาจะถือว่าดำเนินการคำนวณ ค้นหา และส่งคืนข้อมูล โดยไม่เปลี่ยนแปลงสิ่งใดภายนอก กล่าวอีกนัยหนึ่งโดยไม่มี "ผลข้างเคียง"
เคล็ดลับที่สวยงามจริงๆ คือการเพิ่มการกระทำที่ "มีประโยชน์" ให้กับพวกเขา นอกเหนือจากงานหลัก
สีหน้าประหลาดใจเมื่อเพื่อนร่วมงานเห็นฟังก์ชันชื่อ is..
, check..
หรือ find...
กำลังเปลี่ยนแปลงอะไรบางอย่าง จะทำให้ขอบเขตเหตุผลของคุณกว้างขึ้นอย่างแน่นอน
อีกวิธีหนึ่งที่ทำให้ประหลาดใจคือการส่งคืนผลลัพธ์ที่ไม่ได้มาตรฐาน
แสดงความคิดเดิมของคุณ! ปล่อยให้การเรียก checkPermission
ส่งกลับไม่ใช่ true/false
แต่เป็นวัตถุที่ซับซ้อนพร้อมผลลัพธ์ของการตรวจสอบ
นักพัฒนาที่พยายามเขียน if (checkPermission(..))
จะสงสัยว่าทำไมมันไม่ทำงาน บอกพวกเขาว่า: “อ่านเอกสาร!” และให้บทความนี้
เต๋าผู้ยิ่งใหญ่ไหลไปทุกที่
ทั้งทางซ้ายและทางขวา
อย่าจำกัดฟังก์ชันด้วยสิ่งที่เขียนไว้ในชื่อ ให้กว้างขึ้น
ตัวอย่างเช่น ฟังก์ชัน validateEmail(email)
สามารถ (นอกเหนือจากการตรวจสอบอีเมลเพื่อความถูกต้อง) สามารถแสดงข้อความแสดงข้อผิดพลาดและขอให้ป้อนอีเมลอีกครั้ง
การดำเนินการเพิ่มเติมไม่ควรชัดเจนจากชื่อฟังก์ชัน นักเขียนโค้ดนินจาที่แท้จริงจะทำให้โค้ดไม่ชัดเจนเช่นกัน
การรวมหลายการกระทำไว้ในที่เดียวจะช่วยป้องกันโค้ดของคุณจากการใช้ซ้ำ
ลองนึกภาพนักพัฒนารายอื่นต้องการเพียงตรวจสอบอีเมล และไม่แสดงข้อความใดๆ ฟังก์ชั่นของคุณ validateEmail(email)
ที่ทำทั้งสองอย่างจะไม่เหมาะกับพวกเขา ดังนั้นพวกเขาจะไม่ทำลายสมาธิของคุณด้วยการถามอะไรเกี่ยวกับเรื่องนี้
“คำแนะนำ” ทั้งหมดข้างต้นมาจากโค้ดจริง... บางครั้งเขียนโดยนักพัฒนาที่มีประสบการณ์ อาจจะมีประสบการณ์มากกว่าคุณด้วยซ้ำ ;)
ทำตามบางส่วนแล้วโค้ดของคุณจะเต็มไปด้วยความประหลาดใจ
ติดตามหลายๆ คน แล้วโค้ดของคุณจะกลายเป็นของคุณอย่างแท้จริง ไม่มีใครอยากเปลี่ยนแปลงมัน
ปฏิบัติตามทั้งหมด แล้วโค้ดของคุณจะกลายเป็นบทเรียนอันมีค่าสำหรับนักพัฒนารุ่นเยาว์ที่กำลังมองหาการรู้แจ้ง