Software Design

🧓 Uncle Bob - Comments

🤔 Clean Code - การคอมเมนต์โค้ดของลุงบ๊อบ

การทำ Clean Code ตอนที่ 2.1 จากวีดีโอของ 🧓 ลุงบ๊อบ หรือ Robert C. Martin หนึ่งในมหาเทพวงการคอมพิวเตอร์ ซึ่งในรอบนี้เราจะมาดูกันว่า ป๋าแกมีมุมมองใน การคอมเมนต์ ยังไงกันบ้างถึงจะคลีนกันฮ๊าฟ 😘 ส่วนใครที่ยังไม่ได้อ่านตอนที่แรกก็กดอ่านได้จากลิงค์นี้เบย 🧓 Uncle Bob - Part 1

ตอนแรกว่าจะอธิบายวีดีโอตัวที่สองให้จบในบทความเดียว แต่พอลองเขียนดูแล้วยาวม๊วกกกก เลยขอแยก Part 2 ออกเป็น 2 ส่วนนะฮ๊าฟ (Inception เอิ๊กๆ 🤣)

แนะนำให้อ่าน บทความนี้เป็นส่วนหนึ่งของบทคอร์ส 👶 Clean Code หากเพื่อนๆแมวน้ำสนใจศึกษาเรียนรู้ว่าการทำ Clean Code ว่ามันคืออะไร? มีอะไรบ้าง? บลาๆ ก็สามารถกดที่ชื่อบทความสีฟ้าๆเข้าไปอ่านได้เลยครัช

🔖 Comment //

เราเขียน Comment เพราะโค้ดตรงนั้นมันเข้าใจได้ยาก นั่นแสดงว่าโค้ดที่ถูก comment ไว้มันไม่สามารถอธิบายเจตนา (Intent) ของมันเองได้ ดังนั้นลุงแกเลยบอกว่า ห้ามเขียนคอมเมนต์ โดยให้เหตุผลตามนี้

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

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

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

  • Zombie Code - เคยเจอป่ะโค้ดที่ถูกใครคอมเมนต์ไว้ก็ไม่รู้? มันทำอะไรก็ไม่รู้? ยังใช้อยู่หรือเปล่าก็ไม่รู้? แล้วถ้าเราต้องแก้โค้ดแถวๆนั้นเราจะแก้ยังไง? (เลวร้ายกว่านั้นดันเขียนว่าห้ามลบไว้ด้วย) เราเรียกของพวกนี้ว่า Zombie Code นั่นเอง

  • ทุกคอมเมนต์คือความล้มเหลวในการทำคลีนโค้ด เพราะคุณไม่สามารถทำโค้ดใส่สื่อเจตนาของมันได้

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

  • ไม่มีคนอ่าน - ถ้าไม่มีปัญหาจริงๆน้อยคนนักที่จะอ่านคอมเมนต์ ดังนั้นมันก็เหมือนเราเสียเวลาเขียนของที่คนไม่อยากอ่านลงไป

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

Tips ลุงบ๊อบแกเปลี่ยนสีคอมเมนต์ใน IDE ให้กลายเป็นสีแดงเด่นๆเลย เวลาเจอคอมเมนต์จะได้เห็นได้ชัดๆ เพื่อไปดูว่ามันเกิดบ้าไรขึ้น แล้วจะได้รู้ว่าทีมยังขาดประสบการณ์เรื่องอะไรจะได้เอาไปสอนกันตอนทำ Code Review นั่นเอง

เกร็ดความรู้ คอมเมนต์ถูกสร้างมาตั้งแต่โบราณ เพราะในสมัยนั้นภาษาคอมพิวเตอร์มีข้อจำกัดเยอะม๊วก เช่น ตั้งชื่อได้ไม่เกิน 6 ตัวอักษร (assembly จ๋าๆยิ่งเลวร้ายเลย) แต่ภาษาสมัยนี้เราไม่มีข้อจำกัดพวกนั้นแล้ว เลยทำให้เราเขียนโค้ดได้เป็นภาษาคน เหมือนเราประพันธ์บทกวีก็มิปาน (ใครเขียนโค้ดเป็นกวีได้ ส่งให้แมวน้ำดูด้วยเด้อ 🤣)

👌 Legal Comments

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

คอมเมนต์ที่เอาไว้บอกว่าโค้ดพวกนี้มีลิขสิทธินะเฟร้ย

🧓 สมัยนี้เรานิยมเขียน copyright เป็นไฟล์แยกแล้ว เช่น Github ก็จะเขียนในไฟล์ LICENSE นั่นเอง

ℹ️ Informative

คอมเมนต์ที่เอาไว้ให้เราเข้าใจของต่างๆได้ง่ายขึ้น เช่น คอมเมนต์ในรูปด้านล่างอธิบายรูปแบบของเวลา

🧓 คอมเมนต์ประเภทนี้ก็สามารถโกหกเราได้เช่นกัน

💭 Explanation of intent

คอมเมนต์ที่อธิบายเจตนาของโค้ด

🧓 ถ้าทำ Extract method แล้วตั้งชื่อใหม่ดีๆ จะไม่มีคอมเมนต์เลยก็ได้

🦮 Clarification

คอมเมนต์ที่ช่วยให้เราเข้าใจโค้ดจุดนั้นๆได้เร็วกว่าการอ่านโค้ดโดยตรง

🧓 มันทำให้เราไม่อ่านว่าโค้ดจริงๆมันทำงานแบบนั้นหรือเปล่า ถ้าเราเขียนคอมเมนต์ผิดล่ะ ?

⚠️ Warning of consequences

คอมเมนต์ที่ช่วยเตือนผลที่จะตามมาจากโค้ดจุดนั้นๆ

เขาเตือนว่าอย่า run เทสตัวนี้นะเฟร้ย นอกจากเอ็งมีเวลาว่าง! เพราะตัวเทสมันจะสร้างไฟล์มา 10 ล้านไฟล์

☑️ TODO

คอมเมนต์ที่ช่วยเตือนความจำเราว่ายังมีอะไรค้างอยู่บ้าง

🧓 บ่อยครั้งที่เราเขียน TODO ไว้ แล้วเราก็ไม่เคยกลับมาทำมันเลย

เกร็ดความรู้ คอมเมนต์ประเภทนี้เราเรียกมันว่า Token ซึ่งมันจะช่วยเอาไว้เตือนความจำเราว่า จุดนี้เรายังไม่ได้ทำนะ จุดนี้เขียนแบบกากๆไปก่อนเดี๋ยวกลับมาทำใหม่ดีๆ บลาๆ ซึ่งจริงๆมันมีหลายตัวเลย เช่น TODO, HACK, NOTE, UNDONE ซึ่งมันจะต่างจากคอมเมนต์ทั่วไปคือ เราจะสามารถเปิดไล่ดูได้จากทั้งโปรแกรมเลยว่ามีของพวกนี้อยู่ตรงไหนบ้างนั่นเอง ลองศึกษาจาก IDE ของแต่ละคนเอาเองเด้อ สำหรับคนที่ใช้ Visual Studio IDE ก็จิ้มที่ชื่อมันได้เลยแมวน้ำใส่ลิงค์ให้ละ

🔍 Amplification

คอมเมนต์ที่ใช้ขยายความเข้าใจ เช่น ทำไมถึงทำแบบนั้น

😅 โดยส่วนตัวแมวน้ำฟังจุดนี้แล้วก็ขัดๆอยู่นะ ว่ามันจำเป็นจริงๆเหรอ? เพราะ ถ้าเคส cover ได้ก็จบละ ตอน refactor จะไม่ใช้ trim ก็ได้ ตราบใดที่เทสเคสผ่านอ่ะนะ (ใครเข้าใจมันจริงจังฝากคอมเมนต์ทีนะจุ๊)

📄 Document in Public API

คอมเมนต์ที่อธิบายการทำงานของ API ของเราให้กับคนนอกทีมรู้ว่ามันมีไว้ทำอะไร

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

👎 Bad Comments

หลังจากที่เห็นคอมเมนต์ที่พอรับได้ เพราะมันเป็นประโยชน์ต่อทีม คราวนี้มาดูคอมเมนต์จำพวกที่ถ้าลุงเห็นแล้วแกจะไล่ลบออกทันทีดูบ้างกันเบย

🥴 Mumbling

คอมเมนต์ที่อ่านแล้วก็ไม่เข้าใจว่ามันคืออะไร เช่น รูปด้านล่าง ก็เข้าใจนะว่าถ้าเกิด exception แล้วจะใช้ค่า default แต่มันไม่มีโค้ดด๋อยไรในบรรทัดนั้นเลยนิหว่า 🤔

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

🎎 Redundant

คอมเมนต์ฟุ่มเฟือย ของที่ไม่ควรคอมเมนต์ก็ไปใส่

🧓 ภายในคอมเมนต์บางทีก็ใช้ชื่อเรียกแปลกๆ

บอกตรงๆว่ารกมาก อย่าทำให้แมวน้ำเห็นเด็ดขาดนะ

🗡️ Mandated

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

🧓 Coding Standard ไม่ใช่เรื่องไม่ดี แต่บางทีคนตั้งกฎก็ใส่ของที่ไม่สมควรลงไป ดังนั้นอะไรที่ชัดเจนด้วยตัวมันเองอยู่แล้ว และไม่ได้ใช้เป็น Public API ก็ไม่จำเป็นต้องใส่ก็ได้

📚 Journal

คอมเมนต์ที่เอาไว้เล่าประวัติศาสตร์ของโค้ดตัวนี้ ถูกแก้ไขเมื่อไหร่? แก้ทำไม? บลาๆ

🧓 สมัยนี้เรามี source control ใช้แล้ว ไม่ต้องไปนั่ง track ของพวกนี้เอง เช่น Github งุย

🤪 Noise

คอมเมนต์ที่น่ารำคาญ ไร้สาระสุดๆในตระกูลคอมเมนต์ทั้งหมด เช่น i++ // เป็นการเพิ่มค่า i ขึ้นไปอีก 1

ไม่บอกก็รู้ว่านั่นคือ Constructor ตูเป็นโปรแกรมเมอร์นะเฟร้ย !!
จะมาเขียนทำด๋อยอ๊ะร๋ายยยยย ตัวล่างสุดเอ็งเขียนผิดด้วยยยยย!!!

👍 Explanation code

อย่าเขียนคอมเมนต์ ให้เขียนโค้ดให้มันอธิบายตัวเองได้เลย เช่น คอมเมนต์ในรูปด้านล่างพยายามอธิบายว่าสิ่งที่เขียนเป็นเงื่อนไขใน if คืออะไร

เราสามารถแก้ง่ายๆให้โค้ดอธิบายตัวมันเองได้ แบบรูปด้านล่าง จะเห็นว่าเงื่อนไขภายใน if สามารถอ่านเป็นภาษาคนได้

💨 Position markers

คอมเมนต์ที่เอาไว้แยกส่วน เช่น จากบรรทัดนี้ลงไปนะคือ method จากบรรทัดนี้ลงไปคือตัวแปรต่างๆ

🧓 ถ้าทำ Coding Standard ดีๆจะไม่ต้องใส่ของพวกนี้เลย และ IDE สมัยนี้ช่วยเรื่องพวกนี้ได้เยอะเลย เช่น Visual Studio ก็ทำ #region ได้นะ

😱 Closing brace

คอมเมนต์ที่เอาไว้บอกว่า วงเล็บปิดนี้เป็นของ statement ไหน ซึ่งสมัยนี้น่าจะไม่มีใครทำแล้วละ แต่สมัยก่อน IDE มันไม่เก่งขนาดนี้

เกร็ดความรู้ ใครมีปัญหาเรื่องตามหาคู่ของวงเล็บไม่เจอ ถ้าเป็น Visual Studio ลองเลื่อน cursor ไปที่วงเล็บ เปิดหรือปิดก็ได้ แล้วกด CTRL + } ดูนะ มันจะวิ่งไปหาคู่วงเล็บของมันทันทีเบย แล้วถ้ากดซ้ำมันก็จะวิ่งกลับไปที่เดิม

🤮 Attribution & Bylines

คอมเมนต์เอาไว้แสดงหน้าที่รับผิดชอบ เช่น ใครรับผิดชอบงานตัวนี้ ใครสร้างไฟล์นี้ บลาๆ

🧓 Source control ช่วยได้นะนู๋ว์ อยากหาตัวผู้ร้ายไม่ยากหรอกแค่ใช้คำสั่ง blame

🙈 Commented-out code

คอมเมนต์ที่เอาโค้ดตรงนั้นออกไปเฉยๆ โดยไม่รู้ว่ายังใช้อยู่หรือเปล่า และคนอื่นที่ไม่รู้เรื่องก็ไม่กล้าไปยุ่งกับโค้ดพวกนั้นด้วย

🧓 ถ้าคอมเมนต์ไว้ เพราะ ในอนาคตอาจจะเอาโค้ดตรงนั้นกลับมาใช้อยู่ ให้ตัดใจลบมันซะ เพราะโค้ดทุกอย่างที่เขียนนั้นอยู่ใน commit อยู่แล้ว ใช้ source control ให้คุ้มซะ

🌈 HTML in comments

คอมเมนต์ที่แทรก tag HTML ลงไปด้วย โดยส่วนใหญ่จะเจอถ้าใช้พวก tool ในการนำ comment ไปสร้างเป็น document แล้วเราจะได้ document ที่สวยงาม

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

🤐 None-local information

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

🙌 ส่งท้ายบท

🧓 คอมเมนต์ไม่ได้แย่ไปทุกตัว แต่ลุงไม่อยากให้เรามี mindset ว่าต้องเขียนคอมเมนต์เพื่อให้โค้ดเข้าใจได้ง่ายขึ้น แต่อยากให้เขียนโค้ดที่มันอธิบายตัวมันเองได้คือสิ่งที่ดีที่สุด เพราะ ไม่มีอะไรที่เป็น document ของระบบได้ดีเท่า source code ที่ทำงานอยู่จริงๆนั่นเอง

สุดท้ายถ้าอยากจะคอมเมนต์ก็ทำไปเถอะ แต่ถ้าทำเสร็จแล้วมันไม่มีประโยชน์ก็อย่า commit มันไปด้วยก็พอ

แนะนำให้อ่าน ในบทนี้ลุงบ๊อบแกแนะนำให้เดฟทุกคนควรจะรู้จัก Design Patterns เพราะมันคือแนวคิดในการแก้ปัญหาที่เจอบ่อยม๊วกในการสร้างซอฟต์แวร์ หากเพื่อนๆสนใจก็สามารถอ่านได้จากลิงค์ด้านล่างนี้เบย

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

🤴 Design Patterns - อันนี้เป็นตัวที่แมวน้ำเขียนไว้ตั้งแต่สมัยยังไม่มีสลัดผักเลย มีครบทุกตัวแต่อ่านแล้วอาจจะเมากาวหน่อยนะ ช่วงนั้นกำลังหัดเดบิวอยู่

บทความนี้ยังไม่จบอย่างที่บอกว่ามันจะแบ่งเป็น 6 ส่วน นี่เป็นแค่ตอนที่ 2-1 เท่านั้นเอง ดังนั้นตามอ่านกันยาวๆต่อได้จากบทความหลัก หรือไม่อยากพลาดก็ติดตามได้จาก Facebook: Mr.Saladpuk ฮั๊ฟ